F # 10: قوائم

أي برمجة جادة بأي لغة سوف تتضمن دائمًا قوائم. وبالتالي ، سيكون من دواعي سرورك معرفة أن F # جيد جدًا ، يدعم القوائم باستخدام وحدة القائمة الخاصة به. القائمة في F # عبارة عن سلسلة مرتبة وغير متغيرة من العناصر من نفس النوع.

إنشاء قائمة


هناك عدة طرق في F # يمكنك إنشاء قائمة.

  • إنشاء قائمة فارغة
  • إنشاء قائمة بسيطة مع العناصر من 1 إلى 10
  • إنشاء قائمة بالأرقام الفردية في النطاق من 1 إلى 10
  • استخدم حلقة for لإنشاء قائمة.

let prettyPrint desc list = printfn desc printfn "%A" list //empty list let listEmpty = [] //simple list let list1 = [1 .. 10 ] //simple list, with step value let list2 = [1 ..2..10 ] //using for loops to create lists let list3 = [for i in 1 .. 10 -> i*2 ] prettyPrint "let listEmpty = []" listEmpty prettyPrint "let list1 = [ 1 .. 10 ]" list1 prettyPrint "let list2 = [ 1 .. 2..10 ]" list2 prettyPrint "[ for i in 1 .. 10 -> i*2 ]" list3 

صورة

يوضح المثال الأخير الموضح أعلاه كيفية استخدام حلقة for لإنشاء قائمة ، رائعة للغاية ، ولكن هناك شيء أكثر برودة وأكثر قوة في مربع الأدوات F # ، وهي قائمة الفهم.

قائمة الفهم هي طريقة قوية تتيح لك إنشاء قوائم باستخدام F # القياسي إلى حد كبير ، والذي يتضمن وظائف / حلقات / شروط ، إلخ.

دعنا نستمر في إلقاء نظرة على مثال لكيفية إنشاء قوائم.

 let is2 x = match x with | 2 -> "YES" | _ -> "NO" //yield directly let list1 = [ yield 1; yield 2; yield 3; ] //yield numbers between 1 and 20 where we use the //Math.Pow function to return a new number let list2 = [for i in 1.0 .. 20.0 do yield Math.Pow(i,2.0) ] //yield only numbers between 1 and 20 that //can be divided by 5 let list3 = [ for i in 1 .. 20 do if i % 5 = 0 then yield i ] //yields YES/NO strings depending on //whether source int = 2 or not let list4 = [for i in 1 .. 5 -> is2 i ] 

صورة

بعض مشغلي قائمة مفيدة


سلبيات المشغل


يمكننا استخدام عامل التشغيل cons "::" لإضافة قيم إلى قائمة حالية ، لذلك لنفترض أن لدينا هذه القائمة:

 let list1 = [1;2;3;4] let list2 = 42 :: list1 

صورة

مشغل التسلسل


عامل تشغيل آخر مفيد للغاية هو عامل التشغيل "@" ، والذي يسمح لك بدمج قوائم من نفس النوع. لذلك ، على سبيل المثال ، إذا كان لدينا هذا:

 let list1 = [1;2;3;4] let list2 = [5;6;7;8] let list3 = list1 @ list2 

صورة

قائمة الوحدة


لا أعتقد أنني أفرط في ذلك عندما أقول إن وحدة القائمة هي وحدة رئيسية في F #. في الواقع ، وثائق MSDN جيدة جدًا مقارنة بالآخرين في F #. لذلك ، لا أعتقد أنه يمكنني إضافة الكثير من الفائدة إلى الأمثلة الموجودة على MSDN ، لكنني سأقدم هنا بعضًا من أجل راحتك ، ولكن يجب عليك دراسة MSDN للحصول على مزيد من المعلومات .

الخصائص


Head
'T
العنصر الأول
Empty
'T list
إرجاع قائمة فارغة بالنوع المحدد
IsEmpty
منطقي
صحيح - إذا لم تكن هناك عناصر في القائمة
بند
'T
عنصر موجود في فهرس محدد
طول
الباحث
عدد العناصر
ذيل
تي قائمة
قائمة بدون العنصر الأول:

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

صورة

مرشح (فلتر)


تُرجع مجموعة جديدة تحتوي فقط على عناصر المجموعة التي تعود دالة التقييم المعيارية لها إلى true. فيما يلي مثال تافه يحدد فقط الأرقام الزوجية من قائمة لإنشاء قائمة جديدة

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

صورة

بحث (بحث)


إرجاع العنصر الأول الذي ترجع هذه الوظيفة إلى صواب. في هذا المثال ، نظرًا لأن القائمة من 1 إلى 100 تحتوي على 5 ، 5 هو الرقم الأول ، وهو مقسوم على 5 ، لذلك هذه هي قيمة الإرجاع:

صورة

للجميع (forall)


يتحقق مما إذا كانت جميع العناصر في المجموعة تفي بتقييم معين. في هذا المثال ، يجب أن تحتوي القائمة بأكملها على 0 للحصول على قيمة الإرجاع الحقيقية.

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

صورة

تنطبق على الجميع (إيتيري)


يطبق هذه الوظيفة على كل عنصر في المجموعة. يشير العدد الصحيح الذي تم تمريره إلى الوظيفة إلى فهرس العنصر.

 let data = ["Cats";"Dogs";"Mice";"Elephants"] data |> List.iteri (fun ix -> printfn "item %d: %s" ix) 

صورة

الترتيب حسب (SortWith)


لفرز القائمة المحددة باستخدام وظيفة المقارنة هذه.

 let list1 = [ ""; "&"; "&&"; "&&&"; ""; "|"; "||"; "|||" ] printfn "Before sorting: " list1 |> printfn "%A" //custom sorting function let sortFunction (string1:string) (string2:string) = if (string1.Length > string2.Length) then 1 else if (string1.Length printfn "After sorting:\n%A" 

صورة

هناك العديد من الوظائف المفيدة في وحدة القائمة ، وهذا مجرد جزء صغير مما يمكنك العثور عليه.

نظرة صغيرة على العودية على القوائم


لن تكتمل أي مناقشة للقوائم دون التحدث عن التكرار ، فالعكس هو ما سيكون المنشور بأكمله ، ولكن الآن ، دعونا نلقي نظرة على ما يتطلبه الأمر لكتابة وظيفة تكرارية تعمل في قائمة في F #.

 let printIt desc x = printfn "%A %A" desc x let rec printList list = match list with | h :: t -> printIt "head=" h printIt "tail=" t printList t | [] -> () printList [1;2;3;4;5] 

لاحظ استخدام الكلمة الأساسية rec ، والتي تخبر المترجم F # أن هذه الوظيفة ستكون متكررة. بدون هذه الكلمة الأساسية ، استدعاء دالة متكررة - ستتلقى رسالة خطأ في الترجمة ، على الرغم من وجود نص خطأ غير واضح للغاية.

صورة

لذلك ، دعونا نرى نتائج المثال تظهر أعلى قليلاً مع القائمة التالية [1 ؛ 2. 3؛ (4)؛ 5]

صورة

يمكنك أن ترى أن كل شيء يعمل بشكل جيد ، وأنه يتوقف عن العمل عندما تتطابق القيمة مع قائمة فارغة ، كما هو متوقع.

Source: https://habr.com/ru/post/ar471998/


All Articles