목록Lists

F#의 목록은 순서가 지정되고 변경할 수 없는 일련의 동일 형식 요소입니다.A list in F# is an ordered, immutable series of elements of the same type. 목록에 대 한 기본 작업을 수행 하려면 목록 모듈의 함수를 사용 합니다.To perform basic operations on lists, use the functions in the List module.

참고

F #에 대 한 docs.microsoft.com API 참조가 완전 하지 않습니다.The docs.microsoft.com API reference for F# is not complete. 끊어진 링크가 있는 경우 대신 F # 핵심 라이브러리 설명서 를 참조 하세요.If you encounter any broken links, reference F# Core Library Documentation instead.

목록 만들기 및 초기화Creating and Initializing Lists

아래 코드 줄에 나와 있는 것처럼 세미콜론으로 구분되고 대괄호로 묶인 요소를 명시적으로 목록 처리하여 목록을 정의할 수 있습니다.You can define a list by explicitly listing out the elements, separated by semicolons and enclosed in square brackets, as shown in the following line of code.

let list123 = [ 1; 2; 3 ]

요소 간에 줄 바꿈을 삽입하고 필요에 따라 세미콜론을 사용할 수도 있습니다.You can also put line breaks between elements, in which case the semicolons are optional. 요소 초기화 식이 더 길거나 각 요소에 대해 주석을 추가하려는 경우에는 이 두 번째 구문을 사용하면 코드를 더 쉽게 읽을 수 있습니다.The latter syntax can result in more readable code when the element initialization expressions are longer, or when you want to include a comment for each element.

let list123 = [
    1
    2
    3 ]

일반적으로 모든 목록 요소는 같은 형식이어야 합니다.Normally, all list elements must be the same type. 단, 요소가 기본 형식으로 지정된 목록에는 파생 형식 요소를 포함할 수 있습니다.An exception is that a list in which the elements are specified to be a base type can have elements that are derived types. 그러므로 ButtonCheckBox가 모두 Control에서 파생되는 아래 코드는 정상적으로 사용 가능합니다.Thus the following is acceptable, because both Button and CheckBox derive from Control.

let myControlList : Control list = [ new Button(); new CheckBox() ]

아래 코드에 나와 있는 것처럼 범위 연산자(..)로 구분된 정수로 표시되는 범위를 사용하여 목록 요소를 정의할 수도 있습니다.You can also define list elements by using a range indicated by integers separated by the range operator (..), as shown in the following code.

let list1 = [ 1 .. 10 ]

빈 목록은 안에 아무 내용이 없는 대괄호 쌍으로 지정됩니다.An empty list is specified by a pair of square brackets with nothing in between them.

// An empty list.
let listEmpty = []

시퀀스 식을 사용하여 목록을 만들 수도 있습니다.You can also use a sequence expression to create a list. 자세한 내용은 시퀀스 식 을 참조 하세요.See Sequence Expressions for more information. 예를 들어 다음 코드는 정수 1~10의 제곱 목록을 만듭니다.For example, the following code creates a list of squares of integers from 1 to 10.

let listOfSquares = [ for i in 1 .. 10 -> i*i ]

목록 사용을 위한 연산자Operators for Working with Lists

::(cons) 연산자를 사용하여 목록에 요소를 연결할 수 있습니다.You can attach elements to a list by using the :: (cons) operator. list1[2; 3; 4]이면 다음 코드는 list2[100; 2; 3; 4]로 작성합니다.If list1 is [2; 3; 4], the following code creates list2 as [100; 2; 3; 4].

let list2 = 100 :: list1

다음 코드와 같이 @ 연산자를 사용하여 호환 형식을 포함하는 목록을 연결할 수 있습니다.You can concatenate lists that have compatible types by using the @ operator, as in the following code. list1[2; 3; 4]이고 list2[100; 2; 3; 4]이면 다음 코드는 list3[2; 3; 4; 100; 2; 3; 4]로 작성합니다.If list1 is [2; 3; 4] and list2 is [100; 2; 3; 4], this code creates list3 as [2; 3; 4; 100; 2; 3; 4].

let list3 = list1 @ list2

목록에서 작업을 수행 하는 함수는 목록 모듈에서 사용할 수 있습니다.Functions for performing operations on lists are available in the List module.

F#의 목록은 변경이 불가능하므로 수정 작업을 수행하면 기존 목록이 수정되는 대신 새 목록이 생성됩니다.Because lists in F# are immutable, any modifying operations generate new lists instead of modifying existing lists.

F #의 목록은 단일 연결 된 목록으로 구현 됩니다. 즉, 목록의 헤드에만 액세스 하는 작업은 O (1)이 고 요소 액세스는 O (n)입니다.Lists in F# are implemented as singly linked lists, which means that operations that access only the head of the list are O(1), and element access is O(n).

속성Properties

목록 형식이 지원하는 속성은 다음과 같습니다.The list type supports the following properties:

속성Property TypeType 설명Description
사장Head 'T 첫 번째 요소입니다.The first element.
비어 있음Empty 'T list 해당 형식의 빈 목록을 반환하는 정적 속성입니다.A static property that returns an empty list of the appropriate type.
IsEmptyIsEmpty bool 목록에 요소가 없으면 true입니다.true if the list has no elements.
항목Item 'T 지정한 인덱스에 있는 요소로서 0부터 시작합니다.The element at the specified index (zero-based).
길이Length int 요소의 수입니다.The number of elements.
TailTail 'T list 첫 번째 요소가 없는 목록입니다.The list without the first element.

이러한 속성을 사용하는 몇 가지 예는 다음과 같습니다.Following are some examples of using these properties.

let list1 = [ 1; 2; 3 ]

// Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))

목록 사용Using Lists

목록을 사용하여 프로그래밍할 때는 적은 양의 코드만으로도 복잡한 작업을 수행할 수 있습니다.Programming with lists enables you to perform complex operations with a small amount of code. 이 섹션에서는 기능적인 프로그래밍에 중요한 일반적인 목록 관련 작업에 대해 설명합니다.This section describes common operations on lists that are important to functional programming.

목록을 사용한 재귀Recursion with Lists

목록을 고유한 방식으로 재귀 프로그래밍 기술에 맞게 사용할 수 있습니다.Lists are uniquely suited to recursive programming techniques. 목록의 모든 요소에 대해 수행해야 하는 작업을 고려해 보세요.Consider an operation that must be performed on every element of a list. 목록 헤드에 대해 작업을 수행한 다음 목록 꼬리(첫 번째 요소를 제외한 원래 목록으로 구성되는 더 작은 목록)를 다음 재귀 수준으로 다시 전달하는 재귀적인 방식으로 이 작업을 수행할 수 있습니다.You can do this recursively by operating on the head of the list and then passing the tail of the list, which is a smaller list that consists of the original list without the first element, back again to the next level of recursion.

이러한 재귀 함수를 작성하려면 패턴 일치에서 cons 연산자(::)를 사용합니다. 그러면 목록 헤드를 꼬리에서 분리할 수 있습니다.To write such a recursive function, you use the cons operator (::) in pattern matching, which enables you to separate the head of a list from the tail.

다음 코드 예제에서는 패턴 일치를 사용하여 목록에 대해 작업을 수행하는 재귀 함수를 구현하는 방법을 보여줍니다.The following code example shows how to use pattern matching to implement a recursive function that performs operations on a list.

let rec sum list =
   match list with
   | head :: tail -> head + sum tail
   | [] -> 0

위의 코드는 작은 목록에서는 효율적으로 작동하지만 큰 목록에서는 스택이 오버플로될 수 있습니다.The previous code works well for small lists, but for larger lists, it could overflow the stack. 위의 코드보다 개선된 다음 코드에서는 재귀 함수 사용을 위한 표준 기술인 누적기 인수를 사용합니다.The following code improves on this code by using an accumulator argument, a standard technique for working with recursive functions. 누적기 인수를 사용하면 함수 꼬리가 재귀적으로 적용되므로 스택 공간이 절약됩니다.The use of the accumulator argument makes the function tail recursive, which saves stack space.

let sum list =
   let rec loop list acc =
       match list with
       | head :: tail -> loop tail (acc + head)
       | [] -> acc
   loop list 0

RemoveAllMultiples 함수는 목록 두 개를 사용하는 재귀 함수입니다.The function RemoveAllMultiples is a recursive function that takes two lists. 첫 번째 목록은 배수를 제거할 숫자를 포함하며 두 번째 목록은 숫자를 제거할 목록입니다.The first list contains the numbers whose multiples will be removed, and the second list is the list from which to remove the numbers. 다음 예의 코드에서는 이 재귀 함수를 사용하여 목록에서 소수가 아닌 숫자를 모두 삭제해 소수만 포함된 목록을 생성합니다.The code in the following example uses this recursive function to eliminate all the non-prime numbers from a list, leaving a list of prime numbers as the result.

let IsPrimeMultipleTest n x =
   x = n || x % n <> 0

let rec RemoveAllMultiples listn listx =
   match listn with
   | head :: tail -> RemoveAllMultiples tail (List.filter (IsPrimeMultipleTest head) listx)
   | [] -> listx


let GetPrimesUpTo n =
    let max = int (sqrt (float n))
    RemoveAllMultiples [ 2 .. max ] [ 1 .. n ]

printfn "Primes Up To %d:\n %A" 100 (GetPrimesUpTo 100)

출력은 다음과 같습니다.The output is as follows:

Primes Up To 100:
[2; 3; 5; 7; 11; 13; 17; 19; 23; 29; 31; 37; 41; 43; 47; 53; 59; 61; 67; 71; 73; 79; 83; 89; 97]

모듈 함수Module Functions

목록 모듈 은 목록의 요소에 액세스 하는 함수를 제공 합니다.The List module provides functions that access the elements of a list. 가장 빠르고 쉽게 액세스할 수 있는 요소는 헤드 요소입니다.The head element is the fastest and easiest to access. 속성 head 또는 모듈 함수 List. head를 사용 합니다.Use the property Head or the module function List.head. Tail 속성 또는 list. tail 함수를 사용 하 여 목록의 꼬리 부분에 액세스할 수 있습니다.You can access the tail of a list by using the Tail property or the List.tail function. 인덱스를 기준으로 요소를 찾으려면 List. n a n 함수를 사용 합니다.To find an element by index, use the List.nth function. List.nth는 목록을 트래버스하므로List.nth traverses the list. 따라서 O (n)입니다.Therefore, it is O(n). 코드에서 List.nth를 자주 사용하는 경우 목록 대신 배열을 사용해볼 수 있습니다.If your code uses List.nth frequently, you might want to consider using an array instead of a list. 배열의 요소 액세스는 O(1)입니다.Element access in arrays is O(1).

목록에 대한 부울 작업Boolean Operations on Lists

IsEmpty 함수는 목록에 요소가 있는지 여부를 확인 합니다.The List.isEmpty function determines whether a list has any elements.

Exists 함수는 목록 요소에 부울 테스트를 적용 하 고, true 어떤 요소가 테스트를 충족 하는지 여부를 반환 합니다.The List.exists function applies a Boolean test to elements of a list and returns true if any element satisfies the test. Array.exists2 는 유사 하지만 두 목록에서 연속 되는 요소 쌍에 대해 작동 합니다.List.exists2 is similar but operates on successive pairs of elements in two lists.

다음 코드는 List.exists의 사용법을 보여줍니다.The following code demonstrates the use of List.exists.

// Use List.exists to determine whether there is an element of a list satisfies a given Boolean expression.
// containsNumber returns true if any of the elements of the supplied list match
// the supplied number.
let containsNumber number list = List.exists (fun elem -> elem = number) list
let list0to3 = [0 .. 3]
printfn "For list %A, contains zero is %b" list0to3 (containsNumber 0 list0to3)

출력은 다음과 같습니다.The output is as follows:

For list [0; 1; 2; 3], contains zero is true

다음 예에서는 List.exists2의 사용법을 보여줍니다.The following example demonstrates the use of List.exists2.

// Use List.exists2 to compare elements in two lists.
// isEqualElement returns true if any elements at the same position in two supplied
// lists match.
let isEqualElement list1 list2 = List.exists2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
let list1to5 = [ 1 .. 5 ]
let list5to1 = [ 5 .. -1 .. 1 ]
if (isEqualElement list1to5 list5to1) then
    printfn "Lists %A and %A have at least one equal element at the same position." list1to5 list5to1
else
    printfn "Lists %A and %A do not have an equal element at the same position." list1to5 list5to1

출력은 다음과 같습니다.The output is as follows:

Lists [1; 2; 3; 4; 5] and [5; 4; 3; 2; 1] have at least one equal element at the same position.

목록의 모든 요소가 조건을 충족 하는지 여부를 테스트 하려는 경우 forall를 사용할 수 있습니다 .You can use List.forall if you want to test whether all the elements of a list meet a condition.

let isAllZeroes list = List.forall (fun elem -> elem = 0.0) list
printfn "%b" (isAllZeroes [0.0; 0.0])
printfn "%b" (isAllZeroes [0.0; 1.0])

출력은 다음과 같습니다.The output is as follows:

true
false

마찬가지로 list.forall2 는 두 목록의 해당 위치에 있는 모든 요소가 각 요소 쌍을 포함 하는 부울 식을 만족 하는지 여부를 확인 합니다.Similarly, List.forall2 determines whether all elements in the corresponding positions in two lists satisfy a Boolean expression that involves each pair of elements.

let listEqual list1 list2 = List.forall2 (fun elem1 elem2 -> elem1 = elem2) list1 list2
printfn "%b" (listEqual [0; 1; 2] [0; 1; 2])
printfn "%b" (listEqual [0; 0; 0] [0; 1; 0])

출력은 다음과 같습니다.The output is as follows:

true
false

목록에 대한 정렬 작업Sort Operations on Lists

List. sort, sortBy및 lists는 함수 정렬 목록을 사용 합니다.The List.sort, List.sortBy, and List.sortWith functions sort lists. 정렬 함수는 이 세 함수 중 사용할 함수를 결정합니다.The sorting function determines which of these three functions to use. List.sort는 기본 제네릭 비교를 사용합니다.List.sort uses default generic comparison. 제네릭 비교에서는 제네릭 비교 함수를 기반으로 전역 연산자를 사용해 값을 비교합니다.Generic comparison uses global operators based on the generic compare function to compare values. 이 함수는 단순한 숫자 형식, 튜플, 레코드, 구분된 공용 구조체, 목록, 배열, 그리고 System.IComparable을 구현하는 모든 형식과 같은 광범위한 요소 형식에서 효율적으로 작동합니다.It works efficiently with a wide variety of element types, such as simple numeric types, tuples, records, discriminated unions, lists, arrays, and any type that implements System.IComparable. System.IComparable을 구현하는 형식의 경우 제네릭 비교에서는 System.IComparable.CompareTo() 함수를 사용합니다.For types that implement System.IComparable, generic comparison uses the System.IComparable.CompareTo() function. 제네릭 비교는 문자열에도 작동하지만 이 경우에는 문화권과 독립적인 정렬 순서를 사용합니다.Generic comparison also works with strings, but uses a culture-independent sorting order. 함수 형식 등의 지원되지 않는 형식에는 제네릭 비교를 사용하면 안 됩니다.Generic comparison should not be used on unsupported types, such as function types. 또한 기본 제네릭 비교의 성능은 작은 구조의 형식에서 가장 우수합니다. 자주 비교하고 정렬해야 하는 큰 구조의 형식에 대해서는 System.IComparable을 구현하고 효율적인 System.IComparable.CompareTo() 메서드 구현을 제공하는 것이 좋습니다.Also, the performance of the default generic comparison is best for small structured types; for larger structured types that need to be compared and sorted frequently, consider implementing System.IComparable and providing an efficient implementation of the System.IComparable.CompareTo() method.

List.sortBy는 정렬 기준으로 사용되는 값을 반환하는 함수를 사용하며 List.sortWith는 비교 함수를 인수로 사용합니다.List.sortBy takes a function that returns a value that is used as the sort criterion, and List.sortWith takes a comparison function as an argument. 비교를 지원하지 않는 형식으로 작업 중이거나 비교 시 문화권 인식 문자열과 같이 보다 복잡한 비교 의미 체계를 사용할 때는 이 두 함수가 유용합니다.These latter two functions are useful when you are working with types that do not support comparison, or when the comparison requires more complex comparison semantics, as in the case of culture-aware strings.

다음 예에서는 List.sort의 사용법을 보여줍니다.The following example demonstrates the use of List.sort.

let sortedList1 = List.sort [1; 4; 8; -2; 5]
printfn "%A" sortedList1

출력은 다음과 같습니다.The output is as follows:

[-2; 1; 4; 5; 8]

다음 예에서는 List.sortBy의 사용법을 보여줍니다.The following example demonstrates the use of List.sortBy.

let sortedList2 = List.sortBy (fun elem -> abs elem) [1; 4; 8; -2; 5]
printfn "%A" sortedList2

출력은 다음과 같습니다.The output is as follows:

[1; -2; 4; 5; 8]

다음 예에서는 List.sortWith의 사용법을 보여줍니다.The next example demonstrates the use of List.sortWith. 이 예에서는 사용자 지정 비교 함수 compareWidgets를 사용하여 먼저 사용자 지정 형식의 한 필드를 비교한 다음 첫 필드의 값이 같으면 다른 필드를 비교합니다.In this example, the custom comparison function compareWidgets is used to first compare one field of a custom type, and then another when the values of the first field are equal.

type Widget = { ID: int; Rev: int }

let compareWidgets widget1 widget2 =
   if widget1.ID < widget2.ID then -1 else
   if widget1.ID > widget2.ID then 1 else
   if widget1.Rev < widget2.Rev then -1 else
   if widget1.Rev > widget2.Rev then 1 else
   0

let listToCompare = [
    { ID = 92; Rev = 1 }
    { ID = 110; Rev = 1 }
    { ID = 100; Rev = 5 }
    { ID = 100; Rev = 2 }
    { ID = 92; Rev = 1 }
    ]

let sortedWidgetList = List.sortWith compareWidgets listToCompare
printfn "%A" sortedWidgetList

출력은 다음과 같습니다.The output is as follows:

[{ID = 92;
Rev = 1;}; {ID = 92;
Rev = 1;}; {ID = 100;
Rev = 2;}; {ID = 100;
Rev = 5;}; {ID = 110;
Rev = 1;}]

목록에 대한 검색 작업Search Operations on Lists

목록에는 다양한 검색 작업이 지원됩니다.Numerous search operations are supported for lists. 가장 간단한 List. find를 사용 하면 지정 된 조건과 일치 하는 첫 번째 요소를 찾을 수 있습니다.The simplest, List.find, enables you to find the first element that matches a given condition.

다음 코드 예제에서는 List.find를 사용하여 목록에서 5로 나눌 수 있는 첫 번째 숫자를 찾습니다.The following code example demonstrates the use of List.find to find the first number that is divisible by 5 in a list.

let isDivisibleBy number elem = elem % number = 0
let result = List.find (isDivisibleBy 5) [ 1 .. 100 ]
printfn "%d " result

해당 결과는 5입니다.The result is 5.

요소를 먼저 변환 해야 하는 경우에는 옵션을 반환 하는 함수를 사용 하 고 첫 번째 옵션 값을 검색 하는 pick를 호출 Some(x) 합니다.If the elements must be transformed first, call List.pick, which takes a function that returns an option, and looks for the first option value that is Some(x). List.pick은 요소를 반환하는 대신 x 결과를 반환합니다.Instead of returning the element, List.pick returns the result x. 일치하는 요소가 없으면 List.pickSystem.Collections.Generic.KeyNotFoundException을 throw합니다.If no matching element is found, List.pick throws System.Collections.Generic.KeyNotFoundException. 다음 코드는 List.pick의 사용법을 보여줍니다.The following code shows the use of List.pick.

let valuesList = [ ("a", 1); ("b", 2); ("c", 3) ]

let resultPick = List.pick (fun elem ->
                    match elem with
                    | (value, 2) -> Some value
                    | _ -> None) valuesList
printfn "%A" resultPick

출력은 다음과 같습니다.The output is as follows:

"b"

다른 검색 작업 그룹인 \Find 및 관련 함수는 옵션 값을 반환 합니다.Another group of search operations, List.tryFind and related functions, return an option value. List.tryFind 함수는 조건을 만족하는 목록의 첫 번째 요소가 있으면 해당 요소를 반환하고 요소가 없으면 옵션 값 None을 반환합니다.The List.tryFind function returns the first element of a list that satisfies a condition if such an element exists, but the option value None if not. 변형 목록. tryFindIndex 는 요소 자체가 아닌 요소 (있는 경우)의 인덱스를 반환 합니다.The variation List.tryFindIndex returns the index of the element, if one is found, rather than the element itself. 다음 코드에서는 이러한 함수를 보여줍니다.These functions are illustrated in the following code.

let list1d = [1; 3; 7; 9; 11; 13; 15; 19; 22; 29; 36]
let isEven x = x % 2 = 0
match List.tryFind isEven list1d with
| Some value -> printfn "The first even value is %d." value
| None -> printfn "There is no even value in the list."

match List.tryFindIndex isEven list1d with
| Some value -> printfn "The first even value is at position %d." value
| None -> printfn "There is no even value in the list."

출력은 다음과 같습니다.The output is as follows:

The first even value is 22.
The first even value is at position 8.

목록에 대한 산술 연산Arithmetic Operations on Lists

합계 및 평균과 같은 일반적인 산술 연산은 목록 모듈에 기본 제공 됩니다.Common arithmetic operations such as sum and average are built into the List module. List. sum을 사용 하려면 목록 요소 형식이 연산자를 지원 하 + 고 값이 0 이어야 합니다.To work with List.sum, the list element type must support the + operator and have a zero value. 모든 기본 제공 연산 형식은 이러한 조건을 만족합니다.All built-in arithmetic types satisfy these conditions. Average를 사용 하 여 작업 하려면 요소 형식이 나머지 없이 나누기를 지원 해야 합니다 .이는 정수 형식을 제외 하지만 부동 소수점 형식을 허용 합니다.To work with List.average, the element type must support division without a remainder, which excludes integral types but allows for floating point types. List. sumByarray.averageby 함수는 함수를 매개 변수로 사용 하며,이 함수의 결과는 합계 또는 평균 값을 계산 하는 데 사용 됩니다.The List.sumBy and List.averageBy functions take a function as a parameter, and this function's results are used to calculate the values for the sum or average.

다음 코드는 List.sum, List.sumByList.average의 사용법을 보여줍니다.The following code demonstrates the use of List.sum, List.sumBy, and List.average.

// Compute the sum of the first 10 integers by using List.sum.
let sum1 = List.sum [1 .. 10]

// Compute the sum of the squares of the elements of a list by using List.sumBy.
let sum2 = List.sumBy (fun elem -> elem*elem) [1 .. 10]

// Compute the average of the elements of a list by using List.average.
let avg1 = List.average [0.0; 1.0; 1.0; 2.0]

printfn "%f" avg1

출력은 1.000000입니다.The output is 1.000000.

다음 코드는 List.averageBy의 사용법을 보여줍니다.The following code shows the use of List.averageBy.

let avg2 = List.averageBy (fun elem -> float elem) [1 .. 10]
printfn "%f" avg2

출력은 5.5입니다.The output is 5.5.

목록 및 튜플Lists and Tuples

튜플을 포함하는 목록은 zip 및 unzip 함수를 통해 조작할 수 있습니다.Lists that contain tuples can be manipulated by zip and unzip functions. 이러한 함수는 단일 값의 두 목록을 튜플 목록 하나로 결합하거나 튜플 목록 하나를 단일 값의 두 목록으로 분리합니다.These functions combine two lists of single values into one list of tuples or separate one list of tuples into two lists of single values. 가장 간단한 List.zip 함수는 단일 요소 목록 두 개를 사용 하 여 단일 튜플 쌍 목록을 생성 합니다.The simplest List.zip function takes two lists of single elements and produces a single list of tuple pairs. 다른 버전인 List.zip3은 단일 요소 목록 세 개를 사용 하 여 세 개의 요소가 포함 된 단일 튜플 목록을 생성 합니다.Another version, List.zip3, takes three lists of single elements and produces a single list of tuples that have three elements. 다음 코드 예제에서는 List.zip의 사용법을 보여줍니다.The following code example demonstrates the use of List.zip.

let list1 = [ 1; 2; 3 ]
let list2 = [ -1; -2; -3 ]
let listZip = List.zip list1 list2
printfn "%A" listZip

출력은 다음과 같습니다.The output is as follows:

[(1, -1); (2, -2); (3; -3)]

다음 코드 예제에서는 List.zip3의 사용법을 보여줍니다.The following code example demonstrates the use of List.zip3.

let list3 = [ 0; 0; 0]
let listZip3 = List.zip3 list1 list2 list3
printfn "%A" listZip3

출력은 다음과 같습니다.The output is as follows:

[(1, -1, 0); (2, -2, 0); (3, -3, 0)]

해당 하는 압축 풀기 버전 (list.unzip3 및 목록)은 튜플에 있는 튜플 및 반환 목록 목록을 사용 합니다. 여기서 첫 번째 목록에는 각 튜플의 첫 번째 요소를 포함 하 고 두 번째 목록에는 각 튜플의 두 번째 요소가 포함 됩니다.The corresponding unzip versions, List.unzip and List.unzip3, take lists of tuples and return lists in a tuple, where the first list contains all the elements that were first in each tuple, and the second list contains the second element of each tuple, and so on.

다음 코드 예제에서는 List. 압축해제를 사용 하는 방법을 보여 줍니다.The following code example demonstrates the use of List.unzip.

let lists = List.unzip [(1,2); (3,4)]
printfn "%A" lists
printfn "%A %A" (fst lists) (snd lists)

출력은 다음과 같습니다.The output is as follows:

([1; 3], [2; 4])
[1; 3] [2; 4]

다음 코드 예제에서는 list.unzip3를 사용 하는 방법을 보여 줍니다.The following code example demonstrates the use of List.unzip3.

let listsUnzip3 = List.unzip3 [(1,2,3); (4,5,6)]
printfn "%A" listsUnzip3

출력은 다음과 같습니다.The output is as follows:

([1; 4], [2; 5], [3; 6])

목록 요소에 대한 작업Operating on List Elements

F#에서는 목록 요소에 대한 여러 작업을 지원합니다.F# supports a variety of operations on list elements. 가장 간단한 방법은 목록의 모든 요소에 대해 함수를 호출할 수 있도록 하는 iter입니다.The simplest is List.iter, which enables you to call a function on every element of a list. List.iter2를 사용 하면 두 목록의 요소에 대 한 작업을 수행할 수 있습니다 . list.iteriList.iter 각 요소의 인덱스가 각 요소에 대해 호출 되는 함수에 인수로 전달 되는 것을 제외 하 고 및의 기능과의 조합 인 list.iteri2를 사용 하는 것을 제외 하 고 List.iter2 List.iteri 와 비슷합니다.Variations include List.iter2, which enables you to perform an operation on elements of two lists, List.iteri, which is like List.iter except that the index of each element is passed as an argument to the function that is called for each element, and List.iteri2, which is a combination of the functionality of List.iter2 and List.iteri. 다음 코드 예제에서는 이러한 함수를 보여줍니다.The following code example illustrates these functions.

let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
List.iter (fun x -> printfn "List.iter: element is %d" x) list1
List.iteri(fun i x -> printfn "List.iteri: element %d is %d" i x) list1
List.iter2 (fun x y -> printfn "List.iter2: elements are %d %d" x y) list1 list2
List.iteri2 (fun i x y ->
                printfn "List.iteri2: element %d of list1 is %d element %d of list2 is %d"
                  i x i y)
            list1 list2

출력은 다음과 같습니다.The output is as follows:

List.iter: element is 1
List.iter: element is 2
List.iter: element is 3
List.iteri: element 0 is 1
List.iteri: element 1 is 2
List.iteri: element 2 is 3
List.iter2: elements are 1 4
List.iter2: elements are 2 5
List.iter2: elements are 3 6
List.iteri2: element 0 of list1 is 1; element 0 of list2 is 4
List.iteri2: element 1 of list1 is 2; element 1 of list2 is 5
List.iteri2: element 2 of list1 is 3; element 2 of list2 is 6

자주 사용 되는 또 다른 함수는 목록 요소를 변환 하는 목록입니다. map을 사용 하면 목록의 각 요소에 함수를 적용 하 고 모든 결과를 새 목록에 넣을 수 있습니다.Another frequently used function that transforms list elements is List.map, which enables you to apply a function to each element of a list and put all the results into a new list. Array.map2list.map3 는 여러 목록을 사용 하는 변형입니다.List.map2 and List.map3 are variations that take multiple lists. Array.mapi2 및 list.를 사용할 수도 있습니다. 요소 외에도 함수는 각 요소의 인덱스를 전달 해야 합니다.You can also use List.mapi and List.mapi2, if, in addition to the element, the function needs to be passed the index of each element. List.mapi2List.mapi의 차이점은 List.mapi2의 경우 목록 두 개를 사용한다는 것뿐입니다.The only difference between List.mapi2 and List.mapi is that List.mapi2 works with two lists. 다음 예에서는 map을 보여 줍니다.The following example illustrates List.map.

let list1 = [1; 2; 3]
let newList = List.map (fun x -> x + 1) list1
printfn "%A" newList

출력은 다음과 같습니다.The output is as follows:

[2; 3; 4]

다음 예제에서는 List.map2의 사용을 보여 줍니다.The following example shows the use of List.map2.

let list1 = [1; 2; 3]
let list2 = [4; 5; 6]
let sumList = List.map2 (fun x y -> x + y) list1 list2
printfn "%A" sumList

출력은 다음과 같습니다.The output is as follows:

[5; 7; 9]

다음 예제에서는 List.map3의 사용을 보여 줍니다.The following example shows the use of List.map3.

let newList2 = List.map3 (fun x y z -> x + y + z) list1 list2 [2; 3; 4]
printfn "%A" newList2

출력은 다음과 같습니다.The output is as follows:

[7; 10; 13]

다음 예제에서는 List.mapi의 사용을 보여 줍니다.The following example shows the use of List.mapi.

let newListAddIndex = List.mapi (fun i x -> x + i) list1
printfn "%A" newListAddIndex

출력은 다음과 같습니다.The output is as follows:

[1; 3; 5]

다음 예제에서는 List.mapi2의 사용을 보여 줍니다.The following example shows the use of List.mapi2.

let listAddTimesIndex = List.mapi2 (fun i x y -> (x + y) * i) list1 list2
printfn "%A" listAddTimesIndex

출력은 다음과 같습니다.The output is as follows:

[0; 7; 18]

Lists 는와 유사 합니다. List.map 단, 각 요소는 목록을 생성 하 고 이러한 모든 목록은 최종 목록에 연결 됩니다.List.collect is like List.map, except that each element produces a list and all these lists are concatenated into a final list. 다음 코드에서는 목록의 각 요소가 숫자 3개를 생성합니다.In the following code, each element of the list generates three numbers. 이러한 숫자는 모두 목록 하나에 수집됩니다.These are all collected into one list.

let collectList = List.collect (fun x -> [for i in 1..3 -> x * i]) list1
printfn "%A" collectList

출력은 다음과 같습니다.The output is as follows:

[1; 2; 3; 2; 4; 6; 3; 6; 9]

부울 조건을 사용 하 고 지정 된 조건을 충족 하는 요소로만 구성 된 새 목록을 생성 하는 list. filter를 사용할 수도 있습니다.You can also use List.filter, which takes a Boolean condition and produces a new list that consists only of elements that satisfy the given condition.

let evenOnlyList = List.filter (fun x -> x % 2 = 0) [1; 2; 3; 4; 5; 6]

그러면 [2; 4; 6] 목록이 생성됩니다.The resulting list is [2; 4; 6].

지도와 필터 목록의 조합입니다 .를 선택 하면 요소를 동시에 변환 하 고 선택할 수 있습니다.A combination of map and filter, List.choose enables you to transform and select elements at the same time. List.choose는 목록의 각 요소에 대한 옵션을 반환하는 함수를 적용하고, 함수가 옵션 값 Some을 반환하면 요소에 대해 새 결과 목록을 반환합니다.List.choose applies a function that returns an option to each element of a list, and returns a new list of the results for elements when the function returns the option value Some.

다음 코드는 List.choose를 사용하여 단어 목록에서 대문자로 표기된 단어를 선택하는 방법을 보여줍니다.The following code demonstrates the use of List.choose to select capitalized words out of a list of words.

let listWords = [ "and"; "Rome"; "Bob"; "apple"; "zebra" ]
let isCapitalized (string1:string) = System.Char.IsUpper string1.[0]
let results = List.choose (fun elem ->
    match elem with
    | elem when isCapitalized elem -> Some(elem + "'s")
    | _ -> None) listWords
printfn "%A" results

출력은 다음과 같습니다.The output is as follows:

["Rome's"; "Bob's"]

여러 목록에 대한 작업Operating on Multiple Lists

여러 목록을 연결할 수 있습니다.Lists can be joined together. 두 목록을 하나로 조인 하려면 List. append를 사용 합니다.To join two lists into one, use List.append. 세 개 이상의 목록을 조인 하려면 concat를 사용 합니다.To join more than two lists, use List.concat.

let list1to10 = List.append [1; 2; 3] [4; 5; 6; 7; 8; 9; 10]
let listResult = List.concat [ [1; 2; 3]; [4; 5; 6]; [7; 8; 9] ]
List.iter (fun elem -> printf "%d " elem) list1to10
printfn ""
List.iter (fun elem -> printf "%d " elem) listResult

접기 및 검사 작업Fold and Scan Operations

모든 목록 요소가 상호 종속되어야 하는 목록 작업도 있습니다.Some list operations involve interdependencies between all of the list elements. 접기 및 검사 작업은 List.iter List.map 각 요소에서 함수를 호출 하는 및와 유사 하지만 이러한 연산은 계산을 통해 정보를 전달 하는 누적기 라는 추가 매개 변수를 제공 합니다.The fold and scan operations are like List.iter and List.map in that you invoke a function on each element, but these operations provide an additional parameter called the accumulator that carries information through the computation.

목록에 대해 계산을 수행하려면 List.fold를 사용합니다.Use List.fold to perform a calculation on a list.

다음 코드 예제에서는 List. 접기 를 사용 하 여 다양 한 작업을 수행 하는 방법을 보여 줍니다.The following code example demonstrates the use of List.fold to perform various operations.

이 함수는 목록을 트래버스합니다. 누적기 acc는 계산이 진행되면서 전달되는 값입니다.The list is traversed; the accumulator acc is a value that is passed along as the calculation proceeds. 첫 번째 인수는 누적기와 목록 요소를 사용하여 해당 목록 요소에 대한 계산의 중간 결과를 반환합니다.The first argument takes the accumulator and the list element, and returns the interim result of the calculation for that list element. 두 번째 인수는 누적기의 초기 값입니다.The second argument is the initial value of the accumulator.

let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 3 ] (sumList [ 1 .. 3 ])

// The following example computes the average of a list.
let averageList list = (List.fold (fun acc elem -> acc + float elem) 0.0 list / float list.Length)

// The following example computes the standard deviation of a list.
// The standard deviation is computed by taking the square root of the
// sum of the variances, which are the differences between each value
// and the average.
let stdDevList list =
    let avg = averageList list
    sqrt (List.fold (fun acc elem -> acc + (float elem - avg) ** 2.0 ) 0.0 list / float list.Length)

let testList listTest =
    printfn "List %A average: %f stddev: %f" listTest (averageList listTest) (stdDevList listTest)

testList [1; 1; 1]
testList [1; 2; 1]
testList [1; 2; 3]

// List.fold is the same as to List.iter when the accumulator is not used.
let printList list = List.fold (fun acc elem -> printfn "%A" elem) () list
printList [0.0; 1.0; 2.5; 5.1 ]

// The following example uses List.fold to reverse a list.
// The accumulator starts out as the empty list, and the function uses the cons operator
// to add each successive element to the head of the accumulator list, resulting in a
// reversed form of the list.
let reverseList list = List.fold (fun acc elem -> elem::acc) [] list
printfn "%A" (reverseList [1 .. 10])

이러한 함수 중 함수 이름에 숫자가 있는 버전은 둘 이상의 목록에 대해 작동합니다.The versions of these functions that have a digit in the function name operate on more than one list. 예를 들어 list.fold2 는 두 개의 목록에서 계산을 수행 합니다.For example, List.fold2 performs computations on two lists.

다음 예에서는 List.fold2의 사용법을 보여줍니다.The following example demonstrates the use of List.fold2.

// Use List.fold2 to perform computations over two lists (of equal size) at the same time.
// Example: Sum the greater element at each list position.
let sumGreatest list1 list2 = List.fold2 (fun acc elem1 elem2 ->
                                              acc + max elem1 elem2) 0 list1 list2

let sum = sumGreatest [1; 2; 3] [3; 2; 1]
printfn "The sum of the greater of each pair of elements in the two lists is %d." sum

List.foldList. scanList.fold 추가 매개 변수의 최종 값을 반환 하지만 List.scan 추가 매개 변수의 최종 값과 함께 중간 값의 목록을 반환 합니다.List.fold and List.scan differ in that List.fold returns the final value of the extra parameter, but List.scan returns the list of the intermediate values (along with the final value) of the extra parameter.

이러한 각 함수에는 목록이 트래버스 되는 순서와 인수의 순서와 다른 역방향 변형 (예: foldBack)이 포함 되어 있습니다.Each of these functions includes a reverse variation, for example, List.foldBack, which differs in the order in which the list is traversed and the order of the arguments. 또한 List.fold 및에 List.foldBack 는 동일한 길이의 두 목록을 사용 하는 list.fold2array.foldback2변형이 있습니다.Also, List.fold and List.foldBack have variations, List.fold2 and List.foldBack2, that take two lists of equal length. 각 요소에 대해 실행되는 함수는 두 목록의 해당 요소를 사용하여 일부 작업을 수행할 수 있습니다.The function that executes on each element can use corresponding elements of both lists to perform some action. 다음 예에서와 같이 두 목록의 요소 형식은 다를 수 있습니다. 여기서 한 목록은 은행 계좌의 거래 금액을 포함하고 다른 목록은 거래 형식(입금 또는 출금)을 포함합니다.The element types of the two lists can be different, as in the following example, in which one list contains transaction amounts for a bank account, and the other list contains the type of transaction: deposit or withdrawal.

// Discriminated union type that encodes the transaction type.
type Transaction =
    | Deposit
    | Withdrawal

let transactionTypes = [Deposit; Deposit; Withdrawal]
let transactionAmounts = [100.00; 1000.00; 95.00 ]
let initialBalance = 200.00

// Use fold2 to perform a calculation on the list to update the account balance.
let endingBalance = List.fold2 (fun acc elem1 elem2 ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2)
                                initialBalance
                                transactionTypes
                                transactionAmounts
printfn "%f" endingBalance

합계와 같은 계산의 경우 List.foldList.foldBack을 사용해도 결과는 동일합니다. 트래버스 순서에 따라 결과가 달라지지 않기 때문입니다.For a calculation like summation, List.fold and List.foldBack have the same effect because the result does not depend on the order of traversal. 다음 예에서는 List.foldBack을 사용하여 목록에 요소를 추가합니다.In the following example, List.foldBack is used to add the elements in a list.

let sumListBack list = List.foldBack (fun acc elem -> acc + elem) list 0
printfn "%d" (sumListBack [1; 2; 3])

// For a calculation in which the order of traversal is important, fold and foldBack have different
// results. For example, replacing fold with foldBack in the listReverse function
// produces a function that copies the list, rather than reversing it.
let copyList list = List.foldBack (fun elem acc -> elem::acc) list []
printfn "%A" (copyList [1 .. 10])

다음 예에서는 은행 계좌 예로 다시 돌아옵니다.The following example returns to the bank account example. 이번에는 새로운 거래 형식인 이자 계산을 추가합니다.This time a new transaction type is added: an interest calculation. 따라서 최종 잔액은 거래 순서에 따라 달라집니다.The ending balance now depends on the order of transactions.

type Transaction2 =
    | Deposit
    | Withdrawal
    | Interest

let transactionTypes2 = [Deposit; Deposit; Withdrawal; Interest]
let transactionAmounts2 = [100.00; 1000.00; 95.00; 0.05 / 12.0 ]
let initialBalance2 = 200.00

// Because fold2 processes the lists by starting at the head element,
// the interest is calculated last, on the balance of 1205.00.
let endingBalance2 = List.fold2 (fun acc elem1 elem2 ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2
                                | Interest -> acc * (1.0 + elem2))
                                initialBalance2
                                transactionTypes2
                                transactionAmounts2
printfn "%f" endingBalance2


// Because foldBack2 processes the lists by starting at end of the list,
// the interest is calculated first, on the balance of only 200.00.
let endingBalance3 = List.foldBack2 (fun elem1 elem2 acc ->
                                match elem1 with
                                | Deposit -> acc + elem2
                                | Withdrawal -> acc - elem2
                                | Interest -> acc * (1.0 + elem2))
                                transactionTypes2
                                transactionAmounts2
                                initialBalance2
printfn "%f" endingBalance3

함수 목록입니다. 는 별도의 누적기를 전달 하는 List.fold List.scan 대신 List.reduce 요소 형식의 두 인수를 사용 하는 함수를 사용 하 고, 이러한 인수 중 하나가 누적기의 역할을 하 여 계산의 중간 결과를 저장 한다는 점을 제외 하면 및와 유사 합니다.The function List.reduce is somewhat like List.fold and List.scan, except that instead of passing around a separate accumulator, List.reduce takes a function that takes two arguments of the element type instead of just one, and one of those arguments acts as the accumulator, meaning that it stores the intermediate result of the computation. List.reduce는 먼저 처음 두 목록 요소에 대해 실행된 후 해당 작업의 결과를 다음 요소와 함께 사용합니다.List.reduce starts by operating on the first two list elements, and then uses the result of the operation along with the next element. 고유한 형식이 지정된 별도의 누적기가 없으므로 List.reduce는 누적기와 요소 형식이 같을 때만 List.fold 대신 사용할 수 있습니다.Because there is not a separate accumulator that has its own type, List.reduce can be used in place of List.fold only when the accumulator and the element type have the same type. 다음 코드는 List.reduce의 사용법을 보여줍니다.The following code demonstrates the use of List.reduce. 제공된 목록에 요소가 없으면 List.reduce는 예외를 throw합니다.List.reduce throws an exception if the list provided has no elements.

다음 코드에서는 첫 번째 람다 식 호출에 인수 2와 4가 사용되며 결과로 6이 반환됩니다. 그 다음 호출에는 인수 6과 10이 사용되며 결과로 16이 반환됩니다.In the following code, the first call to the lambda expression is given the arguments 2 and 4, and returns 6, and the next call is given the arguments 6 and 10, so the result is 16.

let sumAList list =
    try
        List.reduce (fun acc elem -> acc + elem) list
    with
       | :? System.ArgumentException as exc -> 0

let resultSum = sumAList [2; 4; 10]
printfn "%d " resultSum

목록과 기타 컬렉션 형식 간 변환Converting Between Lists and Other Collection Types

List 모듈은 시퀀스와 배열 간 변환을 위한 함수를 제공합니다.The List module provides functions for converting to and from both sequences and arrays. 시퀀스에서 또는 시퀀스로 변환 하려면 list. toseq 또는 List. ofseq를 사용 합니다.To convert to or from a sequence, use List.toSeq or List.ofSeq. 배열과 변환 하려면 list. toArray 또는 List. ofarray를 사용 합니다.To convert to or from an array, use List.toArray or List.ofArray.

추가 작업Additional Operations

목록의 추가 작업에 대 한 자세한 내용은 라이브러리 참조 항목 컬렉션. 목록 모듈을 참조 하세요.For information about additional operations on lists, see the library reference topic Collections.List Module.

참고 항목See also