Listeleri (F#)
Bir liste içindeki F# aynı türdeki öğeleri sıralı, Immutable dizisidir.
Listeler oluşturma ve başlatma
Liste öğeleri noktalı virgüllerle ayrılmış ve aşağıdaki kod satırında gösterildiği gibi köşeli parantez içine dışarı açıkça listeleyerek tanımlayabilirsiniz.
let list123 = [ 1; 2; 3 ]
Öğeler arasındaki satır sonlarını da koyabilirsiniz, noktalı durumda isteğe bağlıdır. İkinci sözdizimi daha okunabilir kod öğesi başlatma ifadeler daha uzun olduğunda veya her öğe için bir açıklama eklemek isterseniz, yol açabilir.
let list123 = [
1
2
3 ]
Normal olarak, tüm liste öğeleri aynı türde olmalıdır. Temel türü olan öğeler olabilir hangi öğeleri belirtilir liste türleri türetilmiş bir özel durumdur. Aşağıdaki nedenle kabul edilebilir, çünkü her ikisi de Button ve CheckBox öğesinden türetilmeli Control.
let myControlList : Control list = [ new Button(); new CheckBox() ]
Aralık işleci tarafından ayrılmış tamsayılar belirttiği aralığı kullanarak liste öğeleri tanımlayabilirsiniz (..), aşağıdaki kodda gösterildiği gibi.
let list1 = [ 1 .. 10 ]
Ayrıca, aşağıdaki kodda olduğu gibi bir döngü yapýsý kullanarak liste tanımlayabilirsiniz.
let listOfSquares = [ for i in 1 .. 10 -> i*i ]
Boş bir liste, bir çift köşeli ayraç ile bunların arasında hiçbir şey tarafından belirtilir.
// An empty list.
let listEmpty = []
Bir sıra ifade, bir liste oluşturmak için de kullanabilirsiniz. "Sıra ifadeler" bakın sıralarını. Örneğin, aşağıdaki kod, tamsayılar karelerinin listesini 1'den 10'a oluşturur.
let squaresList = [ for i in 1 .. 10 -> i * i ]
Listelerle çalışma için operatörleri
Liste öğelerini kullanarak iliştirebilirsiniz :: (olumsuz) işleci. If list1 is [2; 3; 4], the following code creates list2 as [100; 2; 3; 4].
let list2 = 100 :: list1
Listeleri kullanarak uyumlu türleri olan art arda eklemek @ operatörü, aşağıdaki kodda olduğu gibi. 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
Listelerde işlemleri gerçekleştirmek için işlevler kullanılabilir listesi modülü.
F# listelerinde sabit olduğundan, varolan listeleri değiştirmek yerine yeni listeleri değiştirme işlemleri oluşturur.
F# listeleri yalnızca listenin kafası erişim işlemlerini o(1) demektir, tek olarak bağlantılı listeler uygulanır ve öğe erişiminizi o (n).
Özellikler
Liste türü aşağıdaki özellikleri destekler:
Özellik |
Tür |
Description |
---|---|---|
'T |
İlk öğe. |
|
'T list |
Bir statik özellik uygun türü boş bir listesini döndürür. |
|
bool |
trueherhangi bir öğe listesi varsa. |
|
'T |
(Sıfır) belirtilen dizin adresindeki öğesi. |
|
int |
Öğe sayısı. |
|
'T list |
İlk öğe olmadan listesi. |
Bu özellikleri kullanarak, bazı örnekler aşağıda verilmektedir.
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
Listeleri ile programlama kodu az miktarda karmaşık işlemler gerçekleştirmenize olanak sağlar. Bu bölümde önemli işlevsel programlama listeleri üzerinde yaygın olarak kullanılan işlemler açıklanmaktadır.
Listeleri ile özyineleme
Listeleri için özyinelemeli programlama tekniklerini benzersiz olarak uygundur. Her bir liste öğesi üzerinde gerçekleştirilen bir işlem düşünün. Liste kafası üzerinde çalışan ve ilk öğe olmadan özgün liste oluşan küçük bir liste listesinin tail geçirerek bu tekrar tekrar yapmak, özyineleme ileri düzeyde yeniden.
Yinelemeli işlevin böyle yazmak için olumsuz işlecini kullanın (::) deseniyle eşleşen içinde sağlar liste başındaki tail ayırmak.
Aşağıdaki kod örneği, desen eşleştirme listesi üzerinde işlemler gerçekleştiren bir işlevi uygulamak için nasıl kullanılacağını gösterir.
let rec sum list =
match list with
| head :: tail -> head + sum tail
| [] -> 0
Önceki kod da küçük listeler için çalışır, ancak daha büyük listeleri için yığın taşması. Aşağıdaki kod, accumulator bağımsız değişken, yinelemeli işlevler ile çalışmak için standart bir teknik kullanarak bu kodu artırır. Accumulator bağımsız değişken kullanımını yığın alanından tasarruf işlevi tail özyinelemeli sağlar.
let sum list =
let rec loop list acc =
match list with
| head :: tail -> loop tail (acc + head)
| [] -> acc
loop list 0
İşlev RemoveAllMultiples iki listeyi götüren bir özyinelemeli işlevdir. İlk listede, katları kaldırılacaktır numaraları içerir ve ikinci liste numaralarını kaldırmak için listeden. Aşağıdaki örnek kodda, tüm olmayan-asal sayıların asal sayıların listesi sonucu olarak bırakarak, bir listeden ortadan kaldırmak için bu işlevi kullanı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 gibidir:
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ü işlevleri
Listesi modülü bir liste öğelerinin erişim işlevleri sağlar. Kafa en hızlı ve kolay erişim öğedir. Özelliği kullanmak kafa veya modül işlevi List.head. Tail listesini kullanarak erişebileceğiniz Tail özelliği veya List.tail işlevi. Dizine göre bir öğe bulmak için List.nth işlevi. List.nthListe erişir. Bu nedenle, o, (n). Kodunuzu kullanıyorsa, List.nth sık sık, bir dizi yerine bir listesini kullanarak düşünmek isteyebilirsiniz. Diziler öğe Access'te o(1) ' dir.
Listeler mantıksal işlemler
List.isEmpty işlevi listesini herhangi bir öğe sahip olup olmadığını belirler.
List.exists işlevi geçerli bir Boole değeri test öğeleri listesini verir ve true herhangi bir öğe sınama karşılayıp karşılamadığını. List.exists2 benzer, ancak art arda çiftleri iki liste öğeleri üzerinde çalışır.
Aşağıdaki kodu kullanımını gösterir 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)
Çıktı aşağıdaki gibidir:
For list [0; 1; 2; 3], contains zero is true
Aşağıdaki örnek kullanımını gösterir 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 gibidir:
Lists [1; 2; 3; 4; 5] and [5; 4; 3; 2; 1] have at least one equal element at the same position.
Kullanabileceğiniz List.forall listesinin tüm öğeler bir koşulu karşılayıp karşılamadığını test etmek istiyor.
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 gibidir:
true
false
Benzer şekilde, List.forall2 ilgili pozisyonlarda iki liste içindeki tüm öğeler öğelerinin her çifti içeren bir Boolean deyim kullanımlı olup olmadığı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 gibidir:
true
false
Listeleri sıralama işlemleri
List.sort, List.sortBy, ve List.sortWith işlevler sıralama listeleri. Sıralama işlevini hangi üç bu işlevlerin kullanılacağını belirler. List.sortVarsayılan Genel karşılaştırma kullanır. Genel karşılaştırma değerleri karşılaştırmak için genel karşılaştırma işlevine bağlı genel işleçler kullanır. Etkili biçimde çok çeşitli sayısal türler basit, dizilerini, kayıtları, discriminated sendikalar, listeleri, diziler ve uygulayan her türlü gibi öğe türleri ile çalışır IComparable. Türleri saðlamanýzý IComparable, genel karşılaştırma kullanır CompareTo işlevi. Genel karşılaştırma da dizelerle çalışır, ancak bir kültür bağımsız sıralama düzenini kullanır. Genel karşılaştırma işlevi türleri gibi desteklenmeyen türlerinde kullanılmamalıdır. Ayrıca, varsayılan genel karşılaştırma performansını küçük yapısal türleri için en iyisidir; Karşılaştırma ve sık sıralanmış gereken büyük yapısal türleri için uygulama göz önünde IComparable ve verimli uygulaması sağlayarak CompareTo yöntemi.
List.sortBySıralama ölçütü olarak kullanılan bir değer döndüren bir işlev alır ve List.sortWith karşılaştırma işlev bağımsız değişken olarak alır. İkincisi bu iki işlev karşılaştırma desteklemez veya ne zaman karşılaştırma kültür-aware dizeleri büyük/küçük harf gibi daha karmaşık karşılaştırma semantiği gerektirir türleriyle çalışırken yararlıdır.
Aşağıdaki örnek kullanımını gösterir List.sort.
let sortedList1 = List.sort [1; 4; 8; -2; 5]
printfn "%A" sortedList1
Çıktı aşağıdaki gibidir:
[-2; 1; 4; 5; 8]
Aşağıdaki örnek kullanımını gösterir List.sortBy.
let sortedList2 = List.sortBy (fun elem -> abs elem) [1; 4; 8; -2; 5]
printfn "%A" sortedList2
Çıktı aşağıdaki gibidir:
[1; -2; 4; 5; 8]
Bir sonraki örnek kullanımını gösterir List.sortWith. Bu örnekte, özel karşılaştırma işlevi compareWidgets önce bir alan karşılaştırmak için kullanılan özel bir tür ve sonra başka bir zaman ilk alan değerlerini eşit.
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 gibidir:
[{ID = 92;
Rev = 1;}; {ID = 92;
Rev = 1;}; {ID = 100;
Rev = 2;}; {ID = 100;
Rev = 5;}; {ID = 110;
Rev = 1;}]
Listelerde arama işlemleri
Çok sayıda arama işlemlerini listeler için desteklenir. Basit, List.find, belirli bir koşula uyan ilk öğeyi bulmanıza olanak sağlar.
Aşağıdaki kod örneği kullanımını gösterir List.find 5'te bir liste olarak bölünebileceği ilk numarayı bulmak için.
let isDivisibleBy number elem = elem % number = 0
let result = List.find (isDivisibleBy 5) [ 1 .. 100 ]
printfn "%d " result
Sonucu 5'tir.
İlk öğeler dönüştürülmüş, çağrı List.pick, bir seçenek verir, bir işlev, alır ve ilk seçenek arar değer olan Some(x). Öðeyi yerine List.pick sonucu verir x. Eşleşen bir öğe bulunursa, List.pick atar KeyNotFoundException. Aşağıdaki kod kullanımını gösterir 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
Çıktı aşağıdaki gibidir:
"b"
Arama işlemi, başka bir grup List.tryFind ve ilgili İşlevler, seçenek değeri döndürür. List.tryFind İşlevini verir, bu tür bir öğe varsa, bir koşulu karşılayan bir liste, ama seçenek değeri ilk öğesinden None değilse. Çeşitleme List.tryFindIndex , öğe yerine bulursa öğenin dizinini döndürür. Bu işlevler aşağıdaki kodda gösterildiği gibidir.
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 gibidir:
The first even value is 22.
The first even value is at position 8.
Listeleri üzerinde aritmetik işlemler
Toplam ve ortalama gibi yaygın aritmetik işlemleri yerleşik listesi modülü. Çalışmak için List.sum, liste öğesi türü desteklemelidir + işleci ve sıfır değerine sahip. Tüm yerleşik aritmetik türleri bu koşulları karşılayıp. Çalışmak için List.average, öğe türünün ayrılmaz türlerini dışarıda bırakır ancak kayan nokta türü için verir kalansız, bölme desteklemesi gerekir. List.sumBy ve List.averageBy işlevler işlev parametre olarak alır ve bu işlevin sonuç değerleri toplamını veya ortalamasını hesaplamak için kullanılır.
Aşağıdaki kodu kullanımını gösterir List.sum, List.sumBy, ve 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
Çıkış 1.000000.
Aşağıdaki kod kullanımını gösterir List.averageBy.
let avg2 = List.averageBy (fun elem -> float elem) [1 .. 10]
printfn "%f" avg2
Çıkış 5.5.
Listeler ve dizilerini
Dizilerini içeren listeleri posta tarafından yönetilebilir ve işlevleri sıkıştırılmış açma. Bu işlevler, iki listesi tek bir değer dizilerini tek bir liste haline birleştirebilir veya dizilerini bir listesi tek bir değer iki liste ayırın. Basit List.zip işlevi iki tek öğeleri listesini alır ve tek bir kayıt düzeni çiftleri listesi üretir. Başka bir versiyonu List.zip3, üç tek öğeleri listesini alır ve üç öğe vardır dizilerini tek bir listesini oluşturur. Aşağıdaki kod örneği kullanımını gösterir 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 gibidir:
[(1, -1); (2, -2); (3; -3)]
Aşağıdaki kod örneği kullanımını gösterir List.zip3.
let list3 = [ 0; 0; 0]
let listZip3 = List.zip3 list1 list2 list3
printfn "%A" listZip3
Çıktı aşağıdaki gibidir:
[(1, -1, 0); (2, -2, 0); (3, -3, 0)]
Karşılık gelen sıkıştırılmış açma sürümleri, List.unzip ve List.unzip3, dizilerini listeleri ve iade listeleri kayıt burada ilk liste her kayıt düzeni ilk tüm öğeleri içerir ve ikinci listede ikinci her kayıt düzeni öğesi içerir, düzeni içinde ve böyle devam eder.
Aşağıdaki kod örneği kullanımını gösterir List.unzip.
let lists = List.unzip [(1,2); (3,4)]
printfn "%A" lists
printfn "%A %A" (fst lists) (snd lists)
Çıktı aşağıdaki gibidir:
([1; 3], [2; 4])
[1; 3] [2; 4]
Aşağıdaki kod örneği kullanımını gösterir List.unzip3.
let listsUnzip3 = List.unzip3 [(1,2,3); (4,5,6)]
printfn "%A" listsUnzip3
Çıktı aşağıdaki gibidir:
([1; 4], [2; 5], [3; 6])
Liste öğeleri üzerinde çalışan
F# liste öğeleri üzerinde işlemleri çeşitli destekler. En basit olan List.iter, her bir liste öğesi üzerinde bir işlev çağrısı sağlar. Değişimleri dahil List.iter2, iki liste öğeleri üzerinde bir işlemi gerçekleştirmenize olanak sağlayan List.iteri, olduğu gibi List.iter her öğenin endeksini her öğe için çağrılan işlev için bağımsız değişken olarak geçirilen dışında ve List.iteri2, işlevlerini birlikte olduğu List.iter2 ve List.iteri. Aşağıdaki kod örneği, bu işlevleri gösterilmiştir.
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 gibidir:
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 öğeleri dönüşümleri başka bir sık kullanılan işlev List.map, her bir liste öğesine bir işlevi uygular ve sonuçları yeni listeye koymak için sağlar. List.map2 ve List.map3 olan birden çok liste yararlanmak değişimleri. Ayrıca List.mapi ve List.mapi2, öğenin yanında işlevi her öğenin endeksini geçirilmesi gerekiyor. Arasındaki tek fark List.mapi2 ve List.mapi olan List.mapi2 iki listeleri ile çalışır. Aşağıdaki örnekte gösterilmektedir List.map.
let list1 = [1; 2; 3]
let newList = List.map (fun x -> x + 1) list1
printfn "%A" newList
Çıktı aşağıdaki gibidir:
[2; 3; 4]
Aşağıdaki örnek kullanımını gösterir 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 gibidir:
[5; 7; 9]
Aşağıdaki örnek kullanımını gösterir 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 gibidir:
[7; 10; 13]
Aşağıdaki örnek kullanımını gösterir List.mapi.
let newListAddIndex = List.mapi (fun i x -> x + i) list1
printfn "%A" newListAddIndex
Çıktı aşağıdaki gibidir:
[1; 3; 5]
Aşağıdaki örnek kullanımını gösterir List.mapi2.
let listAddTimesIndex = List.mapi2 (fun i x y -> (x + y) * i) list1 list2
printfn "%A" listAddTimesIndex
Çıktı aşağıdaki gibidir:
[0; 7; 18]
List.Collect gibi List.map, her öğe listesini oluşturur ve bu listeler son listeye birleşir. Aşağıdaki kodda, üç sayı her bir liste öğesi oluşturur. Bunların tümünü tek bir liste haline toplanır.
let collectList = List.collect (fun x -> [for i in 1..3 -> x * i]) list1
printfn "%A" collectList
Çıktı aşağıdaki gibidir:
[1; 2; 3; 2; 4; 6; 3; 6; 9]
Ayrıca List.filter, mantıksal bir koşul alır ve verilen koşula uyan öğeleri içeren yeni bir liste oluşturur.
let evenOnlyList = List.filter (fun x -> x % 2 = 0) [1; 2; 3; 4; 5; 6]
Sonuç listesi [2; 4; 6].
Harita ve filtrenin birleşimini a List.choose , dönüştürme ve aynı anda öğelerini seçin sağlar. List.chooseHer liste öğesi için bir seçenek verir ve işlev seçenek değerini verir, yeni öğeler için sonuç listesini döndürür bir işlev geçerli Some.
Aşağıdaki kodu kullanımını gösterir List.choose sözcükler listesi dışında büyük harfli sözcükleri seçmek için.
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 gibidir:
["Rome's"; "Bob's"]
Birden çok liste üzerinde çalışan
Listeleri birlikte katılabilir. İki liste birisine katılmak için kullanmak List.append. İkiden fazla listeleri katılmak için 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
Katlama ve tarama işlemleri
Tüm liste öğeleri arasındaki karşılıklı bağımlılıkları bazı liste işlemleri içerir. Katlama ve tarama işlemlerini gibidir List.iter ve List.map işlevi her öğe üzerinde çağırır, ancak bu işlemleri adlı ek bir parametreye sağlamak bakımından accumulator , SD aracılığıyla bilgi taşır.
Use List.fold bir listesini bir hesaplama gerçekleştirmek için.
Aşağıdaki kod örneği kullanımını gösterir List.fold çeşitli işlemleri gerçekleştirmek için.
Listenin sonuna ulaşıldığında; accumulator acc hesaplama devam ettikçe, birlikte geçirilen bir değerdir. İlk bağımsız değişken accumulator ve liste öğesi alır ve Ara o liste öğesinin Hesaplama sonucunu verir. İkinci bağımsız değişken accumulator başlangıç 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])
Sürümler işlev adı bir rakam olması bu işlevlerin birden fazla liste üzerinde çalışır. Örneğin, List.fold2 iki liste üzerinde hesaplamaları gerçekleştirir.
Aşağıdaki örnek kullanımını gösterir 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.foldve List.scan farklı List.fold son ek parametre değerini döndürür, ancak List.scan (son değer) birlikte orta değerleri ek parametre listesini döndürür.
Bu işlevlerden her biri, geriye doğru bir değişim içeren List.foldBack, hangi sırayla farklıdır, listenin sonuna ulaşıldığında ve bağımsız değişkenlerin sırası. Ayrıca, List.fold ve List.foldBack çeşitliliğe sahip List.fold2 ve List.foldBack2, iki listeyi eşit uzunlukta olması. Her öğe üzerinde yürütür işlevi her iki liste, karşılık gelen elemanları bazı eylemleri gerçekleştirmek için kullanabilirsiniz. İki liste öğesi türleri içinde bir listesini içeren bir banka hesabı için hareket tutarları aşağıdaki örnekte olduğu gibi farklı olabilir ve diğer listeden işlem türünü içerir: havale veya mevzuatı.
// 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
Toplam, benzer bir hesaplama List.fold ve List.foldBack sonucu çapraz geçiş sırasına göre olmadýðýndan aynı etkiye sahiptir. Aşağıdaki örnekte, List.foldBack bir liste içindeki öğeleri eklemek için kullanılır.
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])
Aşağıdaki örnek, banka hesabı örneği döndürür. Bu kez yeni bir hareket türü eklenir: vade farkı hesaplaması. Kapanış bakiyesinin sırasına göre hareketler şimdi 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
İşlev List.reduce olduğu gibi biraz List.fold ve List.scan, dışında ayrı bir accumulator etrafında geçirme yerine List.reduce sürer öğesinin iki baðýmsýz deðiþken alýr işlevi yalnızca bir yerine yazın ve Ara Hesaplama sonucunu sakladığı yani accumulator davranan bu bağımsız değişkenlerden biri. List.reduceilk iki liste öğeleri üzerinde çalıştırılarak başlar ve sonraki öğe ile birlikte işleminin sonucu kullanır. Kendi türüne sahip ayrı bir accumulator olmadığından List.reduce yerine kullanılan List.fold sadece ne zaman accumulator ve öğe türü aynı türe sahip. Aşağıdaki kodu kullanımını gösterir List.reduce. List.reduceSağlanan listeden hiçbir öğe varsa bir istisna atar.
Aşağıdaki kodda, lambda ifade ilk çağrısına bağımsız değişkeni, 2 ve 4 verilir ve 6 verir ve sonucu 16, bu nedenle sonraki aramanın 6 ve 10, bağımsız verilir.
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
Listeleri ve diğer koleksiyon türleri arasında dönüştürme
List Modülü serileri ve Diziler gelen ve dönüştürme işlevlerini sağlar. Ya da bir sırasından dönüştürmek için kullanın List.toSeq veya List.ofSeq. Ya da bir diziden dönüştürmek için kullanın List.toArray veya List.ofArray.
Ek işlemleri
Listelerde ek işlemleri hakkında daha fazla bilgi için Kitaplık Başvurusu konusuna Collections.List Modülü (F#).