시퀀스Sequences

참고

이 문서의 API 참조 링크를 통해 MSDN으로 이동됩니다.The API reference links in this article will take you to MSDN. docs.microsoft.com API 참조가 완전하지 않습니다.The docs.microsoft.com API reference is not complete.

시퀀스 는 단일 형식의 논리적 일련의 요소입니다.A sequence is a logical series of elements all of one type. 시퀀스는 광범위 하 고 정렬 된 데이터 컬렉션이 있지만 모든 요소를 반드시 사용할 필요는 없는 경우에 특히 유용 합니다.Sequences are particularly useful when you have a large, ordered collection of data but do not necessarily expect to use all of the elements. 개별 시퀀스 요소는 필요에 따라 계산 되므로 모든 요소가 사용 되지 않는 상황에서 시퀀스는 목록 보다 더 나은 성능을 제공할 수 있습니다.Individual sequence elements are computed only as required, so a sequence can provide better performance than a list in situations in which not all the elements are used. 시퀀스는의 seq<'T> System.Collections.Generic.IEnumerable별칭인 형식으로 표현 됩니다.Sequences are represented by the seq<'T> type, which is an alias for System.Collections.Generic.IEnumerable. 따라서을 구현 System.IEnumerable 하는 모든 .NET Framework 형식을 시퀀스로 사용할 수 있습니다.Therefore, any .NET Framework type that implements System.IEnumerable can be used as a sequence. Seq 모듈 은 시퀀스와 관련 된 조작을 지원 합니다.The Seq module provides support for manipulations involving sequences.

시퀀스 식Sequence Expressions

시퀀스 식은 시퀀스로 계산 되는 식입니다.A sequence expression is an expression that evaluates to a sequence. 시퀀스 식은 많은 폼을 사용할 수 있습니다.Sequence expressions can take a number of forms. 가장 간단한 형태는 범위를 지정 합니다.The simplest form specifies a range. 예를 들어 seq { 1 .. 5 } 는 끝점 1과 5를 포함 하 여 다섯 개의 요소를 포함 하는 시퀀스를 만듭니다.For example, seq { 1 .. 5 } creates a sequence that contains five elements, including the endpoints 1 and 5. 두 개의 double 기간 사이에 증가 (또는 감소)를 지정할 수도 있습니다.You can also specify an increment (or decrement) between two double periods. 예를 들어 다음 코드는 10의 배수로 이루어진 시퀀스를 만듭니다.For example, the following code creates the sequence of multiples of 10.

// Sequence that has an increment.
seq { 0 .. 10 .. 100 }

시퀀스 식은 시퀀스의 값을 F# 생성 하는 식으로 구성 됩니다.Sequence expressions are made up of F# expressions that produce values of the sequence. 키워드를 yield 사용 하 여 시퀀스의 일부가 될 값을 생성할 수 있습니다.They can use the yield keyword to produce values that become part of the sequence.

예를 들면 다음과 같습니다.Following is an example.

seq { for i in 1 .. 10 do yield i * i }

-> 대신 연산자를 사용할 수 있습니다 .이 do 경우 다음 예제와 같이 키워드를 생략할 수 있습니다. yieldYou can use the -> operator instead of yield, in which case you can omit the do keyword, as shown in the following example.

seq { for i in 1 .. 10 -> i * i }

다음 코드에서는 표를 나타내는 배열에 대 한 인덱스와 함께 좌표 쌍의 목록을 생성 합니다.The following code generates a list of coordinate pairs along with an index into an array that represents the grid.

let (height, width) = (10, 10)
seq { for row in 0 .. width - 1 do
         for col in 0 .. height - 1 do
           yield (row, col, row*width + col)
    }

시퀀스에 사용 되는 식은필터입니다.ifAn if expression used in a sequence is a filter. 예를 들어, 형식이 isprime int -> bool인 함수를 포함 하 고 있다고 가정 하 고 소수 숫자만 포함 하는 시퀀스를 생성 하려면 다음과 같이 시퀀스를 생성 합니다.For example, to generate a sequence of only prime numbers, assuming that you have a function isprime of type int -> bool, construct the sequence as follows.

seq { for n in 1 .. 100 do if isprime n then yield n }

반복에서 또는 yield -> 를 사용 하는 경우 각 반복은 시퀀스의 단일 요소를 생성 해야 합니다.When you use yield or -> in an iteration, each iteration is expected to generate a single element of the sequence. 각 반복에서 요소 시퀀스를 생성 하는 경우 yield!를 사용 합니다.If each iteration produces a sequence of elements, use yield!. 이 경우 각 반복에서 생성 되는 요소가 연결 되어 최종 시퀀스를 생성 합니다.In that case, the elements generated on each iteration are concatenated to produce the final sequence.

시퀀스 식에서 여러 식을 함께 결합할 수 있습니다.You can combine multiple expressions together in a sequence expression. 각 식에서 생성 된 요소는 함께 연결 됩니다.The elements generated by each expression are concatenated together. 예를 보려면이 항목의 "예" 섹션을 참조 하십시오.For an example, see the "Examples" section of this topic.

Examples

첫 번째 예에서는 반복, 필터 및 양보를 포함 하는 시퀀스 식을 사용 하 여 배열을 생성 합니다.The first example uses a sequence expression that contains an iteration, a filter, and a yield to generate an array. 이 코드는 1에서 100 사이의 일련 번호 시퀀스를 콘솔에 출력 합니다.This code prints a sequence of prime numbers between 1 and 100 to the console.

// Recursive isprime function.
let isprime n =
    let rec check i =
        i > n/2 || (n % i <> 0 && check (i + 1))
    check 2

let aSequence = seq { for n in 1..100 do if isprime n then yield n }
for x in aSequence do
    printfn "%d" x

다음 코드에서는를 yield 사용 하 여 세 개의 요소로 구성 된 튜플로 구성 된 곱하기 테이블을 만듭니다. 각 요소는 두 개의 요소와 제품으로 구성 됩니다.The following code uses yield to create a multiplication table that consists of tuples of three elements, each consisting of two factors and the product.

let multiplicationTable =
  seq { for i in 1..9 do
            for j in 1..9 do
               yield (i, j, i*j) }

다음 예제에서는를 사용 yield! 하 여 개별 시퀀스를 단일 최종 시퀀스로 결합 하는 방법을 보여 줍니다.The following example demonstrates the use of yield! to combine individual sequences into a single final sequence. 이 경우 이진 트리의 각 하위 트리에 대 한 시퀀스는 재귀적 함수에서 연결 되어 최종 시퀀스를 생성 합니다.In this case, the sequences for each subtree in a binary tree are concatenated in a recursive function to produce the final sequence.

// Yield the values of a binary tree in a sequence.
type Tree<'a> =
   | Tree of 'a * Tree<'a> * Tree<'a>
   | Leaf of 'a

// inorder : Tree<'a> -> seq<'a>
let rec inorder tree =
    seq {
      match tree with
          | Tree(x, left, right) ->
               yield! inorder left
               yield x
               yield! inorder right
          | Leaf x -> yield x
    }

let mytree = Tree(6, Tree(2, Leaf(1), Leaf(3)), Leaf(9))
let seq1 = inorder mytree
printfn "%A" seq1

시퀀스 사용Using Sequences

시퀀스는 목록과동일한 많은 기능을 지원 합니다.Sequences support many of the same functions as lists. 시퀀스는 키 생성 함수를 사용 하 여 그룹화 및 계산 등의 작업도 지원 합니다.Sequences also support operations such as grouping and counting by using key-generating functions. 시퀀스는 버킷이라고을 추출 하는 더 다양 한 함수도 지원 합니다.Sequences also support more diverse functions for extracting subsequences.

목록, 배열, 집합 및 맵과 같은 많은 데이터 형식은 열거 가능한 컬렉션 이므로 암시적으로 시퀀스 됩니다.Many data types, such as lists, arrays, sets, and maps are implicitly sequences because they are enumerable collections. 시퀀스를 인수로 사용 하는 함수는을 구현 F# System.Collections.Generic.IEnumerable<'T>하는 .NET Framework 데이터 형식 외에도 모든 공통 데이터 형식에서 사용할 수 있습니다.A function that takes a sequence as an argument works with any of the common F# data types, in addition to any .NET Framework data type that implements System.Collections.Generic.IEnumerable<'T>. 목록을 인수로 사용 하는 함수와 대조 하 여 목록만 사용할 수 있습니다.Contrast this to a function that takes a list as an argument, which can only take lists. 형식은 seq<'T> 에 대 한 IEnumerable<'T>형식 약어입니다.The type seq<'T> is a type abbreviation for IEnumerable<'T>. 즉, 배열, 목록, 집합 및 맵을 System.Collections.Generic.IEnumerable<'T> F#포함 하는 제네릭를 구현 하는 모든 형식 및 대부분의 .NET Framework 컬렉션 형식은 seq 형식과 호환 되며 시퀀스가 필요한 모든 곳에서 사용할 수 있습니다. .This means that any type that implements the generic System.Collections.Generic.IEnumerable<'T>, which includes arrays, lists, sets, and maps in F#, and also most .NET Framework collection types, is compatible with the seq type and can be used wherever a sequence is expected.

모듈 함수Module Functions

Fsharp.core 네임 스페이스Seq 모듈 에는 시퀀스 작업을 위한 함수가 포함 되어 있습니다.The Seq module in the Microsoft.FSharp.Collections namespace contains functions for working with sequences. 이러한 함수는 모두 열거 가능 하므로 시퀀스로 처리 될 수 있기 때문에 목록, 배열, 맵 및 집합 에서도 작동 합니다.These functions work with lists, arrays, maps, and sets as well, because all of those types are enumerable, and therefore can be treated as sequences.

시퀀스 만들기Creating Sequences

앞에서 설명한 대로 시퀀스 식을 사용 하거나 특정 함수를 사용 하 여 시퀀스를 만들 수 있습니다.You can create sequences by using sequence expressions, as described previously, or by using certain functions.

Seq를 사용 하 여 빈 시퀀스를 만들거나 seq. singleton을 사용 하 여 지정 된 요소의 시퀀스를 만들 수 있습니다.You can create an empty sequence by using Seq.empty, or you can create a sequence of just one specified element by using Seq.singleton.

let seqEmpty = Seq.empty
let seqOne = Seq.singleton 10

Seq. init 를 사용 하면 사용자가 제공 하는 함수를 사용 하 여 요소가 생성 되는 시퀀스를 만들 수 있습니다.You can use Seq.init to create a sequence for which the elements are created by using a function that you provide. 또한 시퀀스의 크기를 제공 합니다.You also provide a size for the sequence. 이 함수는 시퀀스가 반복 될 때까지 요소가 생성 되지 않는다는 점을 제외 하 고는 List. init와 동일 합니다.This function is just like List.init, except that the elements are not created until you iterate through the sequence. 다음 코드에서는를 사용 Seq.init하는 방법을 보여 줍니다.The following code illustrates the use of Seq.init.

let seqFirst5MultiplesOf10 = Seq.init 5 (fun n -> n * 10)
Seq.iter (fun elem -> printf "%d " elem) seqFirst5MultiplesOf10

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

0 10 20 30 40

Seq. ofArraySeq. ofarray<> 함수를 사용 하 여 배열 및 목록에서 시퀀스를 만들 수 있습니다.By using Seq.ofArray and Seq.ofList<'T> Function, you can create sequences from arrays and lists. 그러나 캐스트 연산자를 사용 하 여 배열 및 목록을 시퀀스로 변환할 수도 있습니다.However, you can also convert arrays and lists to sequences by using a cast operator. 다음 코드에서는 두 가지 방법을 모두 보여 줍니다.Both techniques are shown in the following code.

// Convert an array to a sequence by using a cast.
let seqFromArray1 = [| 1 .. 10 |] :> seq<int>
// Convert an array to a sequence by using Seq.ofArray.
let seqFromArray2 = [| 1 .. 10 |] |> Seq.ofArray

Seq. 캐스트를 사용 하 여에 System.Collections정의 된 것과 같은 약하게 형식화 된 컬렉션에서 시퀀스를 만들 수 있습니다.By using Seq.cast, you can create a sequence from a weakly typed collection, such as those defined in System.Collections. 이러한 약하게 형식화 된 컬렉션은 요소 형식을 System.Object 가지 며 제네릭이 System.Collections.Generic.IEnumerable&#96;1 아닌 형식을 사용 하 여 열거 됩니다.Such weakly typed collections have the element type System.Object and are enumerated by using the non-generic System.Collections.Generic.IEnumerable&#96;1 type. 다음 코드에서는를 사용 Seq.cast 하 여를 시퀀스로 System.Collections.ArrayList 변환 하는 방법을 보여 줍니다.The following code illustrates the use of Seq.cast to convert an System.Collections.ArrayList into a sequence.

open System
let mutable arrayList1 = new System.Collections.ArrayList(10)
for i in 1 .. 10 do arrayList1.Add(10) |> ignore
let seqCast : seq<int> = Seq.cast arrayList1

Seq. initinfinite 함수를 사용 하 여 무한 시퀀스를 정의할 수 있습니다.You can define infinite sequences by using the Seq.initInfinite function. 이러한 시퀀스의 경우 요소의 인덱스에서 각 요소를 생성 하는 함수를 제공 합니다.For such a sequence, you provide a function that generates each element from the index of the element. 지연 계산으로 인해 무한 시퀀스를 사용할 수 있습니다. 요소는 지정 된 함수를 호출 하 여 필요에 따라 만들어집니다.Infinite sequences are possible because of lazy evaluation; elements are created as needed by calling the function that you specify. 다음 코드 예제에서는 부동 소수점 숫자의 무한 시퀀스를 생성 합니다 .이 경우 연속 되는 정수의 사각형 reciprocals 교대로 반복 되는 연속 된 정수입니다.The following code example produces an infinite sequence of floating point numbers, in this case the alternating series of reciprocals of squares of successive integers.

let seqInfinite = Seq.initInfinite (fun index ->
    let n = float( index + 1 )
    1.0 / (n * n * (if ((index + 1) % 2 = 0) then 1.0 else -1.0)))
printfn "%A" seqInfinite

펼침 는 상태를 사용 하는 계산 함수에서 시퀀스를 생성 하 고 시퀀스의 각 후속 요소를 생성 하도록 변환 합니다.Seq.unfold generates a sequence from a computation function that takes a state and transforms it to produce each subsequent element in the sequence. 상태는 각 요소를 계산 하는 데 사용 되는 값 이며 각 요소가 계산 될 때 변경 될 수 있습니다.The state is just a value that is used to compute each element, and can change as each element is computed. 에 대 Seq.unfold 한 두 번째 인수는 시퀀스를 시작 하는 데 사용 되는 초기 값입니다.The second argument to Seq.unfold is the initial value that is used to start the sequence. Seq.unfold는 상태에 대해 옵션 유형을 사용 합니다 .이를 통해 None 값을 반환 하 여 시퀀스를 종료할 수 있습니다.Seq.unfold uses an option type for the state, which enables you to terminate the sequence by returning the None value. 다음 코드에서는 seq1 unfold 작업에 의해 생성 되는 및 fib시퀀스의 두 가지 예를 보여 줍니다.The following code shows two examples of sequences, seq1 and fib, that are generated by an unfold operation. 첫 번째 seq1는 숫자를 20 개까지 포함 하는 간단한 시퀀스 일 뿐입니다.The first, seq1, is just a simple sequence with numbers up to 20. 두 번째 fib는를 사용 unfold 하 여 피보나치 시퀀스를 계산 합니다.The second, fib, uses unfold to compute the Fibonacci sequence. 피보나치 시퀀스의 각 요소는 이전의 두 피보나치 번호의 합계 이므로 상태 값은 시퀀스의 이전 두 숫자로 구성 된 튜플입니다.Because each element in the Fibonacci sequence is the sum of the previous two Fibonacci numbers, the state value is a tuple that consists of the previous two numbers in the sequence. 초기 값은 시퀀스 (1,1)에서 처음 두 개의 숫자입니다.The initial value is (1,1), the first two numbers in the sequence.

let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
let fib = Seq.unfold (fun state ->
    if (snd state > 1000) then None
    else Some(fst state + snd state, (snd state, fst state + snd state))) (1,1)
printfn "\nThe sequence fib contains Fibonacci numbers."
for x in fib do printf "%d " x

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

The sequence seq1 contains numbers from 0 to 20.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

The sequence fib contains Fibonacci numbers.

2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

다음 코드는 무한 시퀀스의 값을 생성 하 고 계산 하기 위해 여기에 설명 된 다양 한 시퀀스 모듈 함수를 사용 하는 예제입니다.The following code is an example that uses many of the sequence module functions described here to generate and compute the values of infinite sequences. 코드를 실행 하는 데 몇 분 정도 걸릴 수 있습니다.The code might take a few minutes to run.

// infiniteSequences.fs
// generateInfiniteSequence generates sequences of floating point
// numbers. The sequences generated are computed from the fDenominator
// function, which has the type (int -> float) and computes the
// denominator of each term in the sequence from the index of that
// term. The isAlternating parameter is true if the sequence has
// alternating signs.
let generateInfiniteSequence fDenominator isAlternating =
    if (isAlternating) then
        Seq.initInfinite (fun index -> 1.0 /(fDenominator index) * (if (index % 2 = 0) then -1.0 else 1.0))
    else
        Seq.initInfinite (fun index -> 1.0 /(fDenominator index))

// The harmonic series is the series of reciprocals of whole numbers.
let harmonicSeries = generateInfiniteSequence (fun index -> float index) false
// The harmonic alternating series is like the harmonic series
// except that it has alternating signs.
let harmonicAlternatingSeries = generateInfiniteSequence (fun index -> float index) true
// This is the series of reciprocals of the odd numbers.
let oddNumberSeries = generateInfiniteSequence (fun index -> float (2 * index - 1)) true
// This is the series of recipocals of the squares.
let squaresSeries = generateInfiniteSequence (fun index -> float (index * index)) false

// This function sums a sequence, up to the specified number of terms.
let sumSeq length sequence =
    Seq.unfold (fun state ->
        let subtotal = snd state + Seq.nth (fst state + 1) sequence
        if (fst state >= length) then None
        else Some(subtotal,(fst state + 1, subtotal))) (0, 0.0)

// This function sums an infinite sequence up to a given value
// for the difference (epsilon) between subsequent terms,
// up to a maximum number of terms, whichever is reached first.
let infiniteSum infiniteSeq epsilon maxIteration =
    infiniteSeq
    |> sumSeq maxIteration
    |> Seq.pairwise
    |> Seq.takeWhile (fun elem -> abs (snd elem - fst elem) > epsilon)
    |> List.ofSeq
    |> List.rev
    |> List.head
    |> snd

// Compute the sums for three sequences that converge, and compare
// the sums to the expected theoretical values.
let result1 = infiniteSum harmonicAlternatingSeries 0.00001 100000
printfn "Result: %f  ln2: %f" result1 (log 2.0)

let pi = Math.PI
let result2 = infiniteSum oddNumberSeries 0.00001 10000
printfn "Result: %f pi/4: %f" result2 (pi/4.0)

// Because this is not an alternating series, a much smaller epsilon
// value and more terms are needed to obtain an accurate result.
let result3 = infiniteSum squaresSeries 0.0000001 1000000
printfn "Result: %f pi*pi/6: %f" result3 (pi*pi/6.0)

요소 검색 및 찾기Searching and Finding Elements

시퀀스는 목록에서 사용할 수 있는 기능을 지원 합니다. Seq. exists, array.exists2, seq. Find, seq. findindex, Seq. pick, seq. trfindseq.Sequences support functionality available with lists: Seq.exists, Seq.exists2, Seq.find, Seq.findIndex, Seq.pick, Seq.tryFind, and Seq.tryFindIndex. 시퀀스에 사용할 수 있는 이러한 함수 버전은 검색 되는 요소 까지만 시퀀스를 평가 합니다.The versions of these functions that are available for sequences evaluate the sequence only up to the element that is being searched for. 예제는 목록을 참조 하세요.For examples, see Lists.

버킷이라고 가져오기Obtaining Subsequences

Seq. 필터seq. 선택 은 시퀀스 요소가 평가 될 때까지 필터링 및 선택이 발생 하지 않는다는 점을 제외 하면 목록에 사용할 수 있는 해당 함수와 유사 합니다.Seq.filter and Seq.choose are like the corresponding functions that are available for lists, except that the filtering and choosing does not occur until the sequence elements are evaluated.

Seq. truncate 은 다른 시퀀스에서 시퀀스를 만들지만 시퀀스를 지정 된 수의 요소로 제한 합니다.Seq.truncate creates a sequence from another sequence, but limits the sequence to a specified number of elements. Seq 는 시퀀스의 시작 부분부터 지정 된 수의 요소만 포함 하는 새 시퀀스를 만듭니다.Seq.take creates a new sequence that contains only a specified number of elements from the start of a sequence. 시퀀스에 지정 된 것 보다 더 많은 요소가 있으면에서 Seq.takeSystem.InvalidOperationExceptionthrow 합니다.If there are fewer elements in the sequence than you specify to take, Seq.take throws a System.InvalidOperationException. Seq.take Seq.truncate 와 의차이는요소수가지정한수보다적으면에서오류를생성하지않는다는것입니다.Seq.truncateThe difference between Seq.take and Seq.truncate is that Seq.truncate does not produce an error if the number of elements is fewer than the number you specify.

다음 코드에서는 및의 동작과의 차이점 Seq.truncate Seq.take을 보여 줍니다.The following code shows the behavior of and differences between Seq.truncate and Seq.take.

let mySeq = seq { for i in 1 .. 10 -> i*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takenSeq = Seq.take 5 mySeq

let truncatedSeq2 = Seq.truncate 20 mySeq
let takenSeq2 = Seq.take 20 mySeq

let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""

// Up to this point, the sequences are not evaluated.
// The following code causes the sequences to be evaluated.
truncatedSeq |> printSeq
truncatedSeq2 |> printSeq
takenSeq |> printSeq
// The following line produces a run-time error (in printSeq):
takenSeq2 |> printSeq

오류가 발생 하기 전의 출력은 다음과 같습니다.The output, before the error occurs, is as follows.

1 4 9 16 25 
1 4 9 16 25 36 49 64 81 100 
1 4 9 16 25 
1 4 9 16 25 36 49 64 81 100

TakeWhile를 사용 하 여 조건자 함수 (부울 함수)를 지정 하 고 조건자가 인 true원래 시퀀스의 요소로 구성 된 다른 시퀀스에서 시퀀스를 만든 다음 첫 번째 요소 앞에서 중지할 수 있습니다. 조건자가를 반환 false하는입니다.By using Seq.takeWhile, you can specify a predicate function (a Boolean function) and create a sequence from another sequence made up of those elements of the original sequence for which the predicate is true, but stop before the first element for which the predicate returns false. Seq. skip 은 다른 시퀀스의 지정 된 수의 첫 번째 요소를 건너뛰고 나머지 요소를 반환 하는 시퀀스를 반환 합니다.Seq.skip returns a sequence that skips a specified number of the first elements of another sequence and returns the remaining elements. SkipWhile 는 조건자가 반환 true되는 한 다른 시퀀스의 첫 번째 요소를 건너뛴 다음 조건자가 반환 false 하는 첫 번째 요소부터 시작 하 여 나머지 요소를 반환 하는 시퀀스를 반환 합니다. .Seq.skipWhile returns a sequence that skips the first elements of another sequence as long as the predicate returns true, and then returns the remaining elements, starting with the first element for which the predicate returns false.

다음 코드 예제에서는 Seq.takeWhile, Seq.skip Seq.skipWhile및의 차이점을 보여 줍니다.The following code example illustrates the behavior of and differences between Seq.takeWhile, Seq.skip, and Seq.skipWhile.

// takeWhile
let mySeqLessThan10 = Seq.takeWhile (fun elem -> elem < 10) mySeq
mySeqLessThan10 |> printSeq

// skip
let mySeqSkipFirst5 = Seq.skip 5 mySeq
mySeqSkipFirst5 |> printSeq

// skipWhile
let mySeqSkipWhileLessThan10 = Seq.skipWhile (fun elem -> elem < 10) mySeq
mySeqSkipWhileLessThan10 |> printSeq

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

1 4 9 
36 49 64 81 100 
16 25 36 49 64 81 100

시퀀스 변환Transforming Sequences

Seq. 쌍 은 입력 시퀀스의 연속 요소가 튜플로 그룹화 되는 새 시퀀스를 만듭니다.Seq.pairwise creates a new sequence in which successive elements of the input sequence are grouped into tuples.

let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
let seqPairwise = Seq.pairwise (seq { for i in 1 .. 10 -> i*i })
printSeq seqPairwise

printfn ""
let seqDelta = Seq.map (fun elem -> snd elem - fst elem) seqPairwise
printSeq seqDelta

Seq 는와 유사 Seq.pairwise합니다. 단, 튜플 시퀀스를 생성 하는 대신 시퀀스에서 인접 한 요소 ( )의 복사본을 포함 하는 배열 시퀀스를 생성 합니다.Seq.windowed is like Seq.pairwise, except that instead of producing a sequence of tuples, it produces a sequence of arrays that contain copies of adjacent elements (a window) from the sequence. 각 배열에 원하는 인접 요소 수를 지정 합니다.You specify the number of adjacent elements you want in each array.

다음 코드 예제에서는 Seq.windowed의 사용법을 보여줍니다.The following code example demonstrates the use of Seq.windowed. 이 경우 창의 요소 수는 3입니다.In this case the number of elements in the window is 3. 이 예제에서는 printSeq앞의 코드 예제에서 정의 된를 사용 합니다.The example uses printSeq, which is defined in the previous code example.

let seqNumbers = [ 1.0; 1.5; 2.0; 1.5; 1.0; 1.5 ] :> seq<float>
let seqWindows = Seq.windowed 3 seqNumbers
let seqMovingAverage = Seq.map Array.average seqWindows
printfn "Initial sequence: "
printSeq seqNumbers
printfn "\nWindows of length 3: "
printSeq seqWindows
printfn "\nMoving average: "
printSeq seqMovingAverage

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

초기 시퀀스:Initial sequence:

1.0 1.5 2.0 1.5 1.0 1.5 

Windows of length 3: 
[|1.0; 1.5; 2.0|] [|1.5; 2.0; 1.5|] [|2.0; 1.5; 1.0|] [|1.5; 1.0; 1.5|] 

Moving average: 
1.5 1.666666667 1.5 1.333333333

여러 시퀀스를 사용 하는 작업Operations with Multiple Sequences

List.zip3seq는 두 개 또는 세 개의 시퀀스를 사용 하 고 튜플 시퀀스를 생성 합니다.Seq.zip and Seq.zip3 take two or three sequences and produce a sequence of tuples. 이러한 함수는 목록에 사용할 수 있는 해당 함수와 유사 합니다.These functions are like the corresponding functions available for lists. 한 시퀀스를 두 개 이상의 시퀀스로 분리 하는 기능이 없습니다.There is no corresponding functionality to separate one sequence into two or more sequences. 시퀀스에이 기능이 필요한 경우 시퀀스를 목록으로 변환 하 고 list. 압축 풀기를 사용 합니다.If you need this functionality for a sequence, convert the sequence to a list and use List.unzip.

정렬, 비교 및 그룹화Sorting, Comparing, and Grouping

목록에 대해 지원 되는 정렬 함수도 시퀀스와 함께 사용할 수 있습니다.The sorting functions supported for lists also work with sequences. 여기에는 seq. sortsortBy가 포함 됩니다.This includes Seq.sort and Seq.sortBy. 이러한 함수는 전체 시퀀스를 반복 합니다.These functions iterate through the whole sequence.

Seq. compareWith 함수를 사용 하 여 두 시퀀스를 비교 합니다.You compare two sequences by using the Seq.compareWith function. 함수는 연속 된 요소를 차례로 비교 하 고, 첫 번째 같지 않은 쌍을 발견할 경우 중지 합니다.The function compares successive elements in turn, and stops when it encounters the first unequal pair. 추가 요소는 비교에 영향을 주지 않습니다.Any additional elements do not contribute to the comparison.

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

let sequence1 = seq { 1 .. 10 }
let sequence2 = seq { 10 .. -1 .. 1 }

// Compare two sequences element by element.
let compareSequences = Seq.compareWith (fun elem1 elem2 ->
    if elem1 > elem2 then 1
    elif elem1 < elem2 then -1
    else 0)

let compareResult1 = compareSequences sequence1 sequence2
match compareResult1 with
| 1 -> printfn "Sequence1 is greater than sequence2."
| -1 -> printfn "Sequence1 is less than sequence2."
| 0 -> printfn "Sequence1 is equal to sequence2."
| _ -> failwith("Invalid comparison result.")

위의 코드에서는 첫 번째 요소만 계산 및 검사 되 고 결과는-1입니다.In the previous code, only the first element is computed and examined, and the result is -1.

Seq.countby 는 각 요소에 대 한 라는 값을 생성 하는 함수를 사용 합니다.Seq.countBy takes a function that generates a value called a key for each element. 각 요소에 대해이 함수를 호출 하 여 각 요소에 대 한 키를 생성 합니다.A key is generated for each element by calling this function on each element. Seq.countBy그런 다음는 키 값을 포함 하는 시퀀스와 키의 각 값을 생성 한 요소 수의 개수를 반환 합니다.Seq.countBy then returns a sequence that contains the key values, and a count of the number of elements that generated each value of the key.

let mySeq1 = seq { 1.. 100 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
let seqResult = Seq.countBy (fun elem -> if elem % 3 = 0 then 0
                                         elif elem % 3 = 1 then 1
                                         else 2) mySeq1

printSeq seqResult

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

(1, 34) (2, 33) (0, 33)

위의 출력은 키 1, 키 2를 생성 한 33 값 및 키 0을 생성 한 33 값을 생성 한 원래 시퀀스의 요소가 34 개 있음을 보여 줍니다.The previous output shows that there were 34 elements of the original sequence that produced the key 1, 33 values that produced the key 2, and 33 values that produced the key 0.

Seq. groupBy를 호출 하 여 시퀀스의 요소를 그룹화 할 수 있습니다.You can group elements of a sequence by calling Seq.groupBy. Seq.groupBy요소에서 키를 생성 하는 시퀀스 및 함수를 사용 합니다.Seq.groupBy takes a sequence and a function that generates a key from an element. 함수는 시퀀스의 각 요소에 대해 실행 됩니다.The function is executed on each element of the sequence. Seq.groupBy각 튜플의 첫 번째 요소가 키이 고 두 번째 요소가 해당 키를 생성 하는 요소의 시퀀스인 경우 튜플 시퀀스를 반환 합니다.Seq.groupBy returns a sequence of tuples, where the first element of each tuple is the key and the second is a sequence of elements that produce that key.

다음 코드 예제에서는를 사용 Seq.groupBy 하 여 1에서 100 사이의 숫자 시퀀스를 고유 키 값이 0, 1, 2 인 세 개의 그룹으로 분할 하는 방법을 보여 줍니다.The following code example shows the use of Seq.groupBy to partition the sequence of numbers from 1 to 100 into three groups that have the distinct key values 0, 1, and 2.

let sequence = seq { 1 .. 100 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
let sequences3 = Seq.groupBy (fun index ->
                                if (index % 3 = 0) then 0
                                  elif (index % 3 = 1) then 1
                                  else 2) sequence
sequences3 |> printSeq

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

(1, seq [1; 4; 7; 10; ...]) (2, seq [2; 5; 8; 11; ...]) (0, seq [3; 6; 9; 12; ...])

Seq를 호출 하 여 중복 요소를 제거 하는 시퀀스를 만들 수 있습니다.You can create a sequence that eliminates duplicate elements by calling Seq.distinct. 또는 각 요소에서 키 생성 함수를 호출 하는 seq.distinctby를 사용할 수 있습니다.Or you can use Seq.distinctBy, which takes a key-generating function to be called on each element. 결과 시퀀스에는 고유 키가 있는 원래 시퀀스의 요소가 포함 됩니다. 이전 요소에 대 한 중복 키를 생성 하는 이후 요소는 삭제 됩니다.The resulting sequence contains elements of the original sequence that have unique keys; later elements that produce a duplicate key to an earlier element are discarded.

다음 코드 예제에서는 Seq.distinct합니다.The following code example illustrates the use of Seq.distinct. Seq.distinct이진 숫자를 나타내는 시퀀스를 생성 한 다음 유일한 고유 요소만 0과 1 임을 보여 주는 것을 보여 줍니다.Seq.distinct is demonstrated by generating sequences that represent binary numbers, and then showing that the only distinct elements are 0 and 1.

let binary n =
    let rec generateBinary n =
        if (n / 2 = 0) then [n]
        else (n % 2) :: generateBinary (n / 2)
    generateBinary n |> List.rev |> Seq.ofList

printfn "%A" (binary 1024)

let resultSequence = Seq.distinct (binary 1024)
printfn "%A" resultSequence

다음 코드에서는 음수 Seq.distinctBy 및 양수가 포함 된 시퀀스를 시작 하 고 절대 값 함수를 키 생성 함수로 사용 하는 방법을 보여 줍니다.The following code demonstrates Seq.distinctBy by starting with a sequence that contains negative and positive numbers and using the absolute value function as the key-generating function. 음수는 시퀀스에서 앞에 표시 되 고 동일한 절대값을 가진 양수 대신 선택 되기 때문에 결과 시퀀스에는 시퀀스의 음수에 해당 하는 모든 양수가 누락 됩니다. 값 또는 키입니다.The resulting sequence is missing all the positive numbers that correspond to the negative numbers in the sequence, because the negative numbers appear earlier in the sequence and therefore are selected instead of the positive numbers that have the same absolute value, or key.

let inputSequence = { -5 .. 10 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
printfn "Original sequence: "
printSeq inputSequence
printfn "\nSequence with distinct absolute values: "
let seqDistinctAbsoluteValue = Seq.distinctBy (fun elem -> abs elem) inputSequence
seqDistinctAbsoluteValue |> printSeq

읽기 전용 및 캐시 된 시퀀스Readonly and Cached Sequences

Seq. readonly 는 시퀀스의 읽기 전용 복사본을 만듭니다.Seq.readonly creates a read-only copy of a sequence. Seq.readonly는 배열과 같은 읽기/쓰기 컬렉션이 있고 원래 컬렉션을 수정 하지 않으려는 경우에 유용 합니다.Seq.readonly is useful when you have a read-write collection, such as an array, and you do not want to modify the original collection. 이 함수는 데이터 캡슐화를 유지 하는 데 사용할 수 있습니다.This function can be used to preserve data encapsulation. 다음 코드 예제에서는 배열을 포함 하는 형식이 생성 됩니다.In the following code example, a type that contains an array is created. 속성은 배열을 노출 하지만 배열을 반환 하는 대신를 사용 Seq.readonly하 여 배열에서 만든 시퀀스를 반환 합니다.A property exposes the array, but instead of returning an array, it returns a sequence that is created from the array by using Seq.readonly.

type ArrayContainer(start, finish) =
    let internalArray = [| start .. finish |]
    member this.RangeSeq = Seq.readonly internalArray
    member this.RangeArray = internalArray

let newArray = new ArrayContainer(1, 10)
let rangeSeq = newArray.RangeSeq
let rangeArray = newArray.RangeArray
// These lines produce an error:
//let myArray = rangeSeq :> int array
//myArray.[0] <- 0
// The following line does not produce an error.
// It does not preserve encapsulation.
rangeArray.[0] <- 0

Seq. cache 는 시퀀스의 저장 된 버전을 만듭니다.Seq.cache creates a stored version of a sequence. Seq.cache 사용 하 여 시퀀스의 재평가를 방지 하거나 시퀀스를 사용 하는 스레드가 여러 개 있는 경우 각 요소가 한 번만 처리 되도록 해야 합니다.Use Seq.cache to avoid reevaluation of a sequence, or when you have multiple threads that use a sequence, but you must make sure that each element is acted upon only one time. 여러 스레드에서 사용 되는 시퀀스를 사용 하는 경우 원래 시퀀스에 대 한 값을 열거 하 고 계산 하는 하나의 스레드를 사용 하 고 나머지 스레드는 캐시 된 시퀀스를 사용할 수 있습니다.When you have a sequence that is being used by multiple threads, you can have one thread that enumerates and computes the values for the original sequence, and remaining threads can use the cached sequence.

시퀀스에 대 한 계산 수행Performing Computations on Sequences

간단한 산술 연산은 seq. average, seq. sum, Array.averageby, seq. sumby등의 목록에서와 같습니다.Simple arithmetic operations are like those of lists, such as Seq.average, Seq.sum, Seq.averageBy, Seq.sumBy, and so on.

Seq. 접기, seq. 감소seq. scan 은 목록에 사용할 수 있는 해당 함수와 유사 합니다.Seq.fold, Seq.reduce, and Seq.scan are like the corresponding functions that are available for lists. 시퀀스는 지원을 나열 하는 이러한 함수의 전체 변형 하위 집합을 지원 합니다.Sequences support a subset of the full variations of these functions that lists support. 자세한 내용 및 예제는 목록을 참조 하십시오.For more information and examples, see Lists.

참고자료See also