Listeler

F# içindeki bir liste, aynı türde sıralı, sabit bir öğe serisidir. Listelerde temel işlemleri gerçekleştirmek için Liste modülündeki işlevleri kullanın.

Liste Oluşturma ve Başlatma

Aşağıdaki kod satırında gösterildiği gibi, öğeleri noktalı virgülle ayırıp köşeli ayraç içine alarak açıkça listeleyerek liste tanımlayabilirsiniz.

let list123 = [ 1; 2; 3 ]

Ayrıca öğeler arasına satır sonları koyabilirsiniz. Bu durumda noktalı virgüller isteğe bağlıdır. İkinci söz dizimi, öğe başlatma ifadeleri daha uzun olduğunda veya her öğe için bir açıklama eklemek istediğinizde daha okunabilir kodla sonuçlanabilir.

let list123 = [ 1; 2; 3 ]

Normalde, tüm liste öğeleri aynı türde olmalıdır. Bir özel durum, öğelerin temel tür olarak belirtildiği bir listenin türetilmiş türlerdeki öğelere sahip olmasıdır. Bu nedenle, hem hem de ButtonCheckBox türetildiğinden Controlaşağıdakiler kabul edilebilir.

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

Liste öğelerini, aşağıdaki kodda gösterildiği gibi aralık işleci ().. ile ayrılmış tamsayılarla belirtilen bir aralık kullanarak da tanımlayabilirsiniz.

let list1 = [ 1..10 ]

Boş bir liste, aralarında hiçbir şey olmayan bir çift köşeli ayraç tarafından belirtilir.

// An empty list.
let listEmpty = []

Liste oluşturmak için bir sıra ifadesi de kullanabilirsiniz. Daha fazla bilgi için bkz . Sıralı İfadeler . Örneğin, aşağıdaki kod 1 ile 10 arasını içeren tamsayı karelerinin listesini oluşturur.

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

Listelerle Çalışma İşleçleri

(eksiler) işlecini :: kullanarak bir listeye öğe ekleyebilirsiniz. ise list1[2; 3; 4], aşağıdaki kod olarak [100; 2; 3; 4]oluştururlist2.

let list2 = 100 :: list1

Aşağıdaki kodda olduğu gibi işlecini @ kullanarak uyumlu türleri olan listeleri birleştirebilirsiniz. ve list1 ise [2; 3; 4]list2[100; 2; 3; 4], bu kod olarak [2; 3; 4; 100; 2; 3; 4]oluşturur.list3

let list3 = list1 @ list2

Listelerde işlem gerçekleştirme işlevleri Liste modülünde bulunur.

F# içindeki listeler sabit olduğundan, değiştirme işlemleri var olan listeleri değiştirmek yerine yeni listeler oluşturur.

F# içindeki listeler tek bağlantılı listeler olarak uygulanır; bu da yalnızca listenin başına erişen işlemlerin O(1) olduğu ve öğe erişiminin O(n) olduğu anlamına gelir.

Properties

Liste türü aşağıdaki özellikleri destekler:

Özellik Türü Açıklama
Kafa 'T İlk öğe.
Boş 'T list Uygun türde boş bir liste döndüren statik özellik.
IsEmpty bool true listede öğe yoksa.
Kalem 'T Belirtilen dizindeki öğe (sıfır tabanlı).
Uzunluk int Öğe sayısı.
Kuyruk 'T list İlk öğesi olmayan liste.

Bu özelliklerin kullanımına bazı örnekler aşağıda verilmiştir.

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))

Listeleri Kullanma

Listelerle programlama, az miktarda kodla karmaşık işlemler gerçekleştirmenizi sağlar. Bu bölümde, işlevsel programlama için önemli olan listelerdeki yaygın işlemler açıklanmaktadır.

Listelerle Özyineleme

Listeler özyinelemeli programlama teknikleri için benzersiz olarak uygundur. Listenin her öğesinde gerçekleştirilmesi gereken bir işlemi düşünün. Bunu yinelemeli olarak, listenin başında çalışarak ve ardından ilk öğe olmadan özgün listeden oluşan daha küçük bir liste olan listenin kuyruğunu bir sonraki özyineleme düzeyine geri geçirerek yapabilirsiniz.

Böyle bir özyinelemeli işlev yazmak için, bir listenin başını kuyruktan ayırmanızı sağlayan desen eşleştirmesinde eksi işlecini (::) kullanırsınız.

Aşağıdaki kod örneği, bir listede işlem gerçekleştiren özyinelemeli bir işlev uygulamak için desen eşleştirmenin nasıl kullanılacağını gösterir.

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

Önceki kod küçük listeler için iyi çalışır, ancak daha büyük listeler için yığın taşabilir. Aşağıdaki kod, özyinelemeli işlevlerle çalışmaya yönelik standart bir teknik olan bir biriktirici bağımsız değişkeni kullanarak bu kodu geliştirir. Akümülatör bağımsız değişkeninin kullanılması, işlev kuyruğunun özyinelemeli olmasını sağlar ve bu da yığın alanından tasarruf sağlar.

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

    loop list 0

işlevi RemoveAllMultiples , iki liste alan özyinelemeli bir işlevdir. İlk liste, katları kaldırılacak sayıları içerir ve ikinci liste de sayıların kaldırılacağı listedir. Aşağıdaki örnekteki kod bu özyinelemeli işlevi kullanarak bir listedeki asal olmayan tüm sayıları ortadan kaldırır ve sonuç olarak asal sayıların listesini bırakır.

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)

Çıktı aşağıdaki şekilde olacaktır:

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]

Modül İşlevleri

Liste modülü, bir listenin öğelerine erişen işlevler sağlar. Head öğesi, erişimi en hızlı ve en kolay öğedir. Head özelliğini veya List.head modül işlevini kullanın. Tail özelliğini veya List.tail işlevini kullanarak listenin kuyruğuna erişebilirsiniz. Dizine göre bir öğe bulmak için List.nth işlevini kullanın. List.nth listeden çapraz geçişler. Bu nedenle, O(n). Kodunuz sık kullanıyorsa List.nth , liste yerine dizi kullanmayı düşünebilirsiniz. Dizilerdeki öğe erişimi O(1) değeridir.

Listelerde Boole İşlemleri

List.isEmpty işlevi, bir listenin herhangi bir öğesi olup olmadığını belirler.

List.exists işlevi bir listenin öğelerine Boole testi uygular ve herhangi bir öğe testi karşılarsa döndürürtrue. List.exists2 benzerdir ancak iki listede birbirini izleyen öğe çiftleri üzerinde çalışır.

Aşağıdaki kod, kullanımını List.existsgösterir.

// 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)

Çıktı aşağıdaki şekilde olacaktır:

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

Aşağıdaki örnekte kullanımı gösterilmektedir 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

Çıktı aşağıdaki şekilde olacaktır:

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

Listenin tüm öğelerinin bir koşulu karşılayıp karşılamadığını test etmek istiyorsanız List.forall kullanabilirsiniz.

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])

Çıktı aşağıdaki şekilde olacaktır:

true
false

Benzer şekilde, List.forall2 , iki listedeki ilgili konumlardaki tüm öğelerin her öğe çiftini içeren bir Boole ifadesini karşılayıp karşılamadığını belirler.

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])

Çıktı aşağıdaki şekilde olacaktır:

true
false

Listelerde Sıralama İşlemleri

List.sort, List.sortBy ve List.sortWith işlevleri listeleri sıralar. Sıralama işlevi, bu üç işlevden hangisinin kullanılacağını belirler. List.sort varsayılan genel karşılaştırmayı kullanır. Genel karşılaştırma, değerleri karşılaştırmak için genel karşılaştırma işlevini temel alan genel işleçleri kullanır. Basit sayısal türler, tanımlama kümeleri, kayıtlar, ayrımcı birleşimler, listeler, diziler ve uygulayan System.IComparableherhangi bir tür gibi çok çeşitli öğe türleriyle verimli bir şekilde çalışır. uygulayan System.IComparabletürler için genel karşılaştırma işlevi System.IComparable.CompareTo() kullanır. Genel karşılaştırma dizelerle de çalışır, ancak kültürden bağımsız bir sıralama düzeni kullanır. İşlev türleri gibi desteklenmeyen türlerde genel karşılaştırma kullanılmamalıdır. Ayrıca, varsayılan genel karşılaştırmanın performansı küçük yapılandırılmış türler için en iyisidir; sık karşılaştırılması ve sıralanması gereken daha büyük yapılandırılmış türler için yöntemi verimli bir şekilde uygulamayı System.IComparable ve sağlamayı System.IComparable.CompareTo() göz önünde bulundurun.

List.sortBy sıralama ölçütü olarak kullanılan bir değer döndüren bir işlev alır ve List.sortWith bir karşılaştırma işlevini bağımsız değişken olarak alır. Bu ikinci iki işlev, karşılaştırmayı desteklemeyen türlerle çalışırken veya kültüre duyarlı dizelerde olduğu gibi karşılaştırma daha karmaşık karşılaştırma semantiği gerektirdiğinde yararlıdır.

Aşağıdaki örnekte kullanımı gösterilmektedir List.sort.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Aşağıdaki örnekte kullanımı gösterilmektedir List.sortBy.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Sonraki örnekte kullanımı gösterilmektedir List.sortWith. Bu örnekte, özel karşılaştırma işlevi compareWidgets önce özel türdeki bir alanı karşılaştırmak için, sonra ilk alanın değerleri eşit olduğunda başka bir alanı karşılaştırmak için kullanılır.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Listelerde Arama İşlemleri

Listeler için çok sayıda arama işlemi desteklenir. En basit olan List.find, belirli bir koşulla eşleşen ilk öğeyi bulmanızı sağlar.

Aşağıdaki kod örneği, bir listede 5'e bölünebilen ilk sayıyı bulmak için öğesinin kullanımını List.find gösterir.

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

Sonuç 5'tir.

Öğelerin önce dönüştürülmesi gerekiyorsa, list.pick öğesini çağırın. Bu, bir seçenek döndüren bir işlev alır ve ilk seçenek değerini ararSome(x). öğesini List.pick döndürmek yerine sonucunu xdöndürür. Eşleşen öğe bulunmazsa, List.pick oluşturur System.Collections.Generic.KeyNotFoundException. Aşağıdaki kod, kullanımını List.pickgösterir.

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

Çıktı aşağıdaki şekilde olacaktır:

"b"

Başka bir arama işlemi grubu olan List.tryFind ve ilgili işlevler bir seçenek değeri döndürür. İşlev, List.tryFind böyle bir öğe varsa bir koşulu karşılayan listenin ilk öğesini, değilse seçenek değerini None döndürür. List.tryFindIndex varyasyonu, öğenin kendisi yerine bir tane bulunursa öğenin dizinini döndürür. Bu işlevler aşağıdaki kodda gösterilmiştir.

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."

Çıktı aşağıdaki şekilde olacaktır:

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

Listelerde Aritmetik İşlemler

Toplam ve ortalama gibi yaygın aritmetik işlemler Liste modülünde yerleşik olarak bulunur. List.sum ile çalışmak için liste öğesi türünün işlecini desteklemesi + ve sıfır değerine sahip olması gerekir. Tüm yerleşik aritmetik türler bu koşulları karşılar. List.average ile çalışmak için, öğe türünün ayrılmaz türleri dışlayan ancak kayan nokta türlerine izin veren kalan bir bölüm olmadan bölmeyi desteklemesi gerekir. List.sumBy ve List.averageBy işlevleri bir işlevi parametre olarak alır ve bu işlevin sonuçları toplam veya ortalama değerlerini hesaplamak için kullanılır.

Aşağıdaki kod, , List.sumByve List.averagekullanımını List.sumgösterir.

// 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

Çıkış 1.000000 olur.

Aşağıdaki kod, kullanımını List.averageBygösterir.

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

Çıkış 5.5 olur.

Listeler ve Demetler

Tanımlama grubu içeren listeler zip ve unzip işlevleriyle değiştirilebilir. Bu işlevler, tek değerlerden oluşan iki listeyi tek bir demet listesinde birleştirir veya bir demet listesini tek değerlerden oluşan iki liste halinde ayırır. En basit List.zip işlevi, tek öğelerden oluşan iki liste alır ve tek bir tanımlama grubu çiftleri listesi oluşturur. Başka bir sürüm olan List.zip3, tek öğelerin üç listesini alır ve üç öğe içeren tek bir tanımlama grubu listesi oluşturur. Aşağıdaki kod örneğinde kullanımı gösterilmektedir List.zip.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Aşağıdaki kod örneğinde kullanımı gösterilmektedir List.zip3.

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

Çıktı aşağıdaki şekilde olacaktır:

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

İlgili unzip sürümleri olan List.unzip ve List.unzip3, bir tanımlama grubundaki demetlerin ve dönüş listelerinin listesini alır; burada ilk liste her demette ilk olan tüm öğeleri içerir ve ikinci liste de her demetin ikinci öğesini içerir vb.

Aşağıdaki kod örneğinde List.unzip kullanımı gösterilmektedir.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Aşağıdaki kod örneği List.unzip3'ün kullanımını gösterir.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Liste Öğeleri üzerinde Çalışma

F# liste öğelerinde çeşitli işlemleri destekler. En basiti, listenin her öğesinde işlev çağırmanızı sağlayan List.iter'dir. Çeşitlemeler, list.iteriList.iter olmak üzere iki listenin öğeleri üzerinde işlem gerçekleştirmenizi sağlayan List.iter2,her öğenin dizininin her öğe için çağrılan işleve bağımsız değişken olarak geçirilmesi dışında, ve List.iteriişlevlerinin List.iter2 bir bileşimi olan List.iteri2'yi içerir. Aşağıdaki kod örneğinde bu işlevler gösterilmektedir.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Liste öğelerini dönüştüren bir diğer sık kullanılan işlev list.map işlevidir. Bu işlev, bir listenin her öğesine işlev uygulamanıza ve tüm sonuçları yeni bir listeye yerleştirmenize olanak tanır. List.map2 ve List.map3 , birden çok liste alan çeşitlemelerdir. Öğeye ek olarak işlevin her öğenin dizinine geçirilmesi gerekiyorsa List.mapi ve List.mapi2 de kullanabilirsiniz. ile List.mapi arasındaki List.mapi2 tek fark, iki listeyle çalışmasıdırList.mapi2. Aşağıdaki örnekte List.map gösterilmektedir.

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

Çıktı aşağıdaki şekilde olacaktır:

[2; 3; 4]

Aşağıdaki örnekte kullanımı gösterilmektedir 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

Çıktı aşağıdaki şekilde olacaktır:

[5; 7; 9]

Aşağıdaki örnekte kullanımı gösterilmektedir List.map3.

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

Çıktı aşağıdaki şekilde olacaktır:

[7; 10; 13]

Aşağıdaki örnekte kullanımı gösterilmektedir List.mapi.

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

Çıktı aşağıdaki şekilde olacaktır:

[1; 3; 5]

Aşağıdaki örnekte kullanımı gösterilmektedir List.mapi2.

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

Çıktı aşağıdaki şekilde olacaktır:

[0; 7; 18]

List.collect gibi List.mapolur, ancak her öğe bir liste oluşturur ve tüm bu listeler son bir liste halinde birleştirilir. Aşağıdaki kodda, listenin her öğesi üç sayı oluşturur. Bunların tümü tek bir listede toplanır.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Ayrıca, Boole koşulu alan ve yalnızca belirtilen koşulu karşılayan öğelerden oluşan yeni bir liste oluşturan List.filter'i de kullanabilirsiniz.

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

Sonuçta elde edilen liste şeklindedir [2; 4; 6].

Harita ve filtrenin bir bileşimi olan List.select, öğeleri aynı anda dönüştürmenizi ve seçmenizi sağlar. List.choose bir listenin her öğesine bir seçenek döndüren bir işlev uygular ve işlev seçenek değerini Somedöndürdüğünde öğeler için sonuçların yeni bir listesini döndürür.

Aşağıdaki kod, sözcük listesinden büyük harfle yazılmış sözcükleri seçmek için öğesinin kullanımını List.choose gösterir.

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

Çıktı aşağıdaki şekilde olacaktır:

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

Birden Çok Listede Çalışma

Listeler birleştirilebilir. İki listeyi bir liste halinde birleştirmek için List.append komutunu kullanın. İkiden fazla listeyi birleştirmek için List.concat'i kullanın.

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

Katlama ve Tarama İşlemleri

Bazı liste işlemleri, tüm liste öğeleri arasında bağımlılıklar içerir. Katlama ve tarama işlemleri, her öğede bir işlev çağırmanız gibi List.iterList.map ve işlemleridir, ancak bu işlemler hesaplama aracılığıyla bilgi taşıyan biriktirici adlı ek bir parametre sağlar.

Listede hesaplama yapmak için kullanın List.fold .

Aşağıdaki kod örneği, çeşitli işlemleri gerçekleştirmek için List.fold kullanımını gösterir.

Listeden geçilir; akümülatör acc , hesaplama devam ederken geçirilen bir değerdir. İlk bağımsız değişken, biriktiriciyi ve liste öğesini alır ve bu liste öğesi için hesaplamanın ara sonucunu döndürür. İkinci bağımsız değişken, biriktiricinin ilk değeridir.

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])

İşlev adında basamak bulunan bu işlevlerin sürümleri birden fazla listede çalışır. Örneğin, List.fold2 iki listede hesaplamalar gerçekleştirir.

Aşağıdaki örnekte kullanımı gösterilmektedir 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.fold ve List.scan , ek parametrenin son değerini döndüren List.fold ve ek parametrenin List.scan ara değerlerinin (son değerle birlikte) listesini döndüren için farklıdır.

Bu işlevlerin her biri, listenin geçiş sırasına ve bağımsız değişkenlerin sırasına göre farklılık gösteren List.foldBack gibi ters bir varyasyon içerir. Ayrıca, List.foldList.foldBack eşit uzunlukta iki liste alan List.fold2 ve List.foldBack2 çeşitlemelerine de sahiptir. Her öğede yürütülen işlev, bazı eylemler gerçekleştirmek için her iki liste için de ilgili öğeleri kullanabilir. İki listenin öğe türleri, aşağıdaki örnekte olduğu gibi farklı olabilir. Bir listede banka hesabı için işlem tutarları, diğer liste ise işlem türünü içerir: para yatırma veya çekme.

// 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

Toplama List.fold gibi bir hesaplama için ve List.foldBack sonuç dolaşma sırasına bağlı olmadığından aynı etkiye sahiptir. Aşağıdaki örnekte, List.foldBack öğeleri listeye eklemek için kullanılır.

let sumListBack list = List.foldBack (fun elem acc -> 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])

Aşağıdaki örnek, banka hesabı örneğine döner. Bu kez yeni bir işlem türü eklenir: faiz hesaplaması. Bitiş bakiyesi artık işlemlerin sırasına bağlıdır.

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.reduce işlevi ve işlevine benzerList.scanList.fold, ancak ayrı bir akümülatörün List.reduce etrafından geçmek yerine yalnızca biri yerine öğe türünün iki bağımsız değişkenini alan bir işlev alır ve bu bağımsız değişkenlerden biri, hesaplamanın ara sonucunu depoladığı anlamına gelir. List.reduce ilk iki liste öğesi üzerinde çalışarak başlar ve ardından sonraki öğeyle birlikte işlemin sonucunu kullanır. Kendi türüne sahip ayrı bir akümülatör olmadığından, List.reduce yalnızca biriktirici ve öğe türü aynı türe sahip olduğunda kullanılabilir List.fold . Aşağıdaki kod, kullanımını List.reducegösterir. List.reduce sağlanan listede öğe yoksa bir özel durum oluşturur.

Aşağıdaki kodda lambda ifadesine yapılan ilk çağrıya 2 ve 4 bağımsız değişkenleri verilir ve 6 döndürür ve sonraki çağrıya 6 ve 10 bağımsız değişkenleri verilir, dolayısıyla sonuç 16 olur.

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

Listeler ve Diğer Koleksiyon Türleri Arasında Dönüştürme

Modül hem List dizilere hem de dizilere dönüştürmeye yönelik işlevler sağlar. Bir diziye veya diziden dönüştürmek için List.toSeq veya List.ofSeq kullanın. Bir diziye veya diziden dönüştürmek için List.toArray veya List.ofArray kullanın.

Ek İşlemler

Listelerde ek işlemler hakkında bilgi için, Liste Modülü kitaplık başvurusu konusuna bakın.

Ayrıca bkz.