صفائف (F#)
هي عبارة عن صفائف مجموعات ذات الحجم ثابت، zero-based، mutable من عناصر بيانات المتتالية التي تعتبر كل من نفس النوع.
إنشاء الصفيف
يمكنك إنشاء صفائف بعدة طرق. يمكنك إنشاء صفيفة مربع متوسط بسرد قيم متتالية بين [| و |] ومفصولة بفاصلة منقوطة، كما هو مبين في الأمثلة التالية.
let array1 = [| 1; 2; 3 |]
You can also put each عنصر تشغيل a separate خط, في which حالة the semicolon فاصل هو اختياري.
let array1 =
[|
1
2
3
|]
The نوع of the صفيفة عناصر هو inferred من the literals used يجب أن يكون الحقل consistent. The following تعليمات برمجية causes an خطأ because 1.0 هو a حُر و 2 و 3 are integers.
// Causes an error.
// let array2 = [| 1.0; 2; 3 |]
You can also استخدم تسلسل expressions إلى إنشاء arrays. Following هو an مثال that creates an مصفوفه من squares of integers من 1 إلى 10.
let array3 = [| for i in 1 .. 10 -> i * i |]
إلى إنشاء an صفيفة في which الجميع the عناصر are initialized إلى zero, استخدم Array.zeroCreate.
let arrayOfTenZeroes : int array = Array.zeroCreate 10
الوصول إلى عناصر
You can الوصول صفيفة عناصر بواسطة using a dot عامل (.) و brackets ([ و ]).
array1.[0]
صفيفة indices البدء عند 0.
You can also الوصول صفيفة عناصر بواسطة using slice notation, which enables you إلى specify a subrange of the صفيفة. أمثلة of slice notation follow.
// Accesses elements from 0 to 2.
array1.[0..2]
// Accesses elements from the beginning of the array to 2.
array1.[..2]
// Accesses elements from 2 to the end of the array.
array1.[2..]
When slice notation هو used, a جديد نسخ of the صفيفة هو تاريخ الإنشاء.
صفيفة أنواع و الوحدات النمطية
The نوع of الجميع F# arrays هو the .NET Framework نوع Array. Therefore, F# arrays دعم الجميع the functionality متوفر في Array.
The مكتبة وحدة نمطية? Microsoft.FSharp.Collections.صفيفة supports العمليات تشغيل واحد-dimensional arrays. The الوحدات النمطية Array2D, Array3D, و Array4D contain دالات that دعم العمليات تشغيل arrays of الثاني, three, و الرابع الأبعاد, respectively. You can إنشاء arrays of يصنف أكبر من الرابع بواسطة using Array.
Simple دالات
صفيفة.يحصل gets an عنصر. صفيفة.الطول يعطي الطول الصفيف. صفيفة.التعيين بتعيين عنصر إلى القيمة محددة. يلي تعليمات برمجية يوضح المثال استخدام هاتين الدالتين.
let array1 = Array.create 10 ""
for i in 0 .. array1.Length - 1 do
Array.set array1 i (i.ToString())
for i in 0 .. array1.Length - 1 do
printf "%s " (Array.get array1 i)
الإخراج هو كما يلي.
0 1 2 3 4 5 6 7 8 9
دالات التي إنشاء الصفيف
عدة دالات إنشاء صفائف دون الحاجة إلى صفيفة موجود. صفيفة.فارغ بإنشاء صفيفة جديد يحتوي على أية عناصر. صفيفة.إنشاء بإنشاء صفيفة الحجم معين و يقوم بتعيين الجميع العناصر إلى قيم المتوفرة. صفيفة.init بإنشاء صفيفة، وإعطاء بعدا ودالة إلى إنشاء العناصر. صفيفة.zeroCreate بإنشاء صفيفة في كل ما عناصر تهيئة إلى القيمة صفر لنوع عنصر الصفيف. يلي تعليمات برمجية يوضح هذه الوظائف.
let myEmptyArray = Array.empty
printfn "Length of empty array: %d" myEmptyArray.Length
printfn "Area of floats set to 5.0: %A" (Array.create 10 5.0)
printfn "Array of squares: %A" (Array.init 10 (fun index -> index * index))
let (myZeroArray : float array) = Array.zeroCreate 10
الإخراج هو كما يلي.
Length of empty array: 0
Area of floats set to 5.0: [|5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0|]
Array of squares: [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81|]
صفيفة.نسخ بإنشاء صفيفة جديد يحتوي على العناصر التي يتم نسخها من صفيفة موجود. لاحظ أن النسخة هو نسخة سطحية، وهو ما يعني أنه عند نوع العنصر هو نوع مرجع، المرجع فقط هو نسخ، وليس على الكائن المصدر. The following تعليمات برمجية مثال illustrates this.
open System.Text
let firstArray : StringBuilder array = Array.init 3 (fun index -> new StringBuilder(""))
let secondArray = Array.copy firstArray
// Reset an element of the first array to a new value.
firstArray.[0] <- new StringBuilder("Test1")
// Change an element of the first array.
firstArray.[1].Insert(0, "Test2") |> ignore
printfn "%A" firstArray
printfn "%A" secondArray
إخراج التعليمة البرمجية السابقة هو كما يلي:
[|Test1; Test2; |]
[|; Test2; |]
سلسلة Test1تظهر فقط في الصفيف أول لأن عملية إنشاء عنصر جديد إلى الكتابة فوق المرجع في firstArrayولكن هل تؤثر الأصلية بالرجوع إلى فارغ السلسلة التي هو ما زالت موجودة في secondArray. سلسلة Test2يظهر في كل من الصفائف لأن Insertالعملية تشغيل StringBuilderيؤثر نوع الأساسية StringBuilderالكائن، الذي هو المشار إليها في كل من الصفائف.
صفيفة.منخفض بإنشاء جديد الصفيف من subrange صفيفة. تحديد subrange بتوفير فهرس البداية و الطول. يلي تعليمات برمجية يوضح استخدم Array.sub.
let a1 = [| 0 .. 99 |]
let a2 = Array.sub a1 5 10
printfn "%A" a2
يظهر الإخراج subarray تبدأ في العنصر 5 ويحتوي على عناصر 10.
[|5; 6; 7; 8; 9; 10; 11; 12; 13; 14|]
صفيفة.append بإنشاء جديد الصفيف بدمج صفيفين موجود.
يلي تعليمات برمجية يوضح Array.append.
printfn "%A" (Array.append [| 1; 2; 3|] [| 4; 5; 6|])
إخراج التعليمة البرمجية السابقة هو كما يلي.
[|1; 2; 3; 4; 5; 6|]
صفيفة.اختيار بتحديد عناصر الصفيف لتضمينها في صفيفة جديدة. يلي تعليمات برمجية يوضح Array.choose. ملاحظة that the عنصر نوع of the صفيفة does not have إلى مطابقة the نوع of the القيمة returned في the خيار نوع. في this مثال, the عنصر نوع هو int و the خيار هو the النتيجة of a polynomial دالة, elem*elem - 1, كـ a عائم يؤشر رقم.
printfn "%A" (Array.choose (fun elem -> if elem % 2 = 0 then
Some(float (elem*elem - 1))
else
None) [| 1 .. 10 |])
إخراج التعليمة البرمجية السابقة هو كما يلي.
[|3.0; 15.0; 35.0; 63.0; 99.0|]
صفيفة.collect runs a specified دالة تشغيل each صفيفة عنصر of an موجود صفيفة و then collects the عناصر generated بواسطة the دالة و combines them في a جديد صفيفة. يلي تعليمات برمجية يوضح Array.collect.
printfn "%A" (Array.collect (fun elem -> [| 0 .. elem |]) [| 1; 5; 10|])
إخراج التعليمة البرمجية السابقة هو كما يلي.
[|0; 1; 0; 1; 2; 3; 4; 5; 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10|]
صفيفة.concat takes a تسلسل of arrays و combines them في a مفرد صفيفة. يلي تعليمات برمجية يوضح Array.concat.
let multiplicationTable max = seq { for i in 1 .. max -> [| for j in 1 .. max -> (i, j, i*j) |] }
printfn "%A" (Array.concat (multiplicationTable 3))
إخراج التعليمة البرمجية السابقة هو كما يلي.
[|(1, 1, 1); (1, 2, 2); (1, 3, 3); (2, 1, 2); (2, 2, 4); (2, 3, 6); (3, 1, 3);
(3, 2, 6); (3, 3, 9)|]
صفيفة.عامل تصفية takes a منطقي شرط دالة و generates a جديد صفيفة that يحتوي على فقط those عناصر من the إدخال صفيفة for which the شرط هو صحيح. يلي تعليمات برمجية يوضح Array.filter.
printfn "%A" (Array.filter (fun elem -> elem % 2 = 0) [| 1 .. 10|])
إخراج التعليمة البرمجية السابقة هو كما يلي.
[|2; 4; 6; 8; 10|]
صفيفة.rev generates a جديد صفيفة بواسطة reversing the ترتيب of an موجود صفيفة. يلي تعليمات برمجية يوضح Array.rev.
let stringReverse (s: string) =
System.String(Array.rev (s.ToCharArray()))
printfn "%A" (stringReverse("!dlrow olleH"))
إخراج التعليمة البرمجية السابقة هو كما يلي.
"Hello world!"
You can بسهولة يجمع دالات في the صفيفة وحدة نمطية? that transform arrays بواسطة using the pipeline عامل (|>), كـ shown في the following مثال.
[| 1 .. 10 |]
|> Array.filter (fun elem -> elem % 2 = 0)
|> Array.choose (fun elem -> if (elem <> 8) then Some(elem*elem) else None)
|> Array.rev
|> printfn "%A"
The إخراج هو
[|100; 36; 16; 4|]
صفيف متعدد الأبعاد
الصفائف متعددة الأبعاد يمكن إنشاؤها، ولكن هناك هو لا بناء الجملة لكتابة حرفية الصفائف متعددة الأبعاد. استخدم the عامل array2D إلى إنشاء an صفيفة من a تسلسلات of تسلسلات of صفيفة عناصر. The تسلسلات can be صفيفة أو قائمة literals. على سبيل المثال، ما يلي تعليمات برمجية إنشاء صفيف ثنائي الأبعاد.
let my2DArray = array2D [ [ 1; 0]; [0; 1] ]
You can also استخدم the دالة Array2D.init إلى يهيّئ arrays of الثاني الأبعاد, و similar دالات are متوفر for arrays of three و الرابع الأبعاد. These دالات take a دالة that هو used إلى إنشاء the عناصر. لإنشاء ثنائي الأبعاد الصفيف الذي يحتوي على عناصر معينة إلى قيمة الابتدائية بدلاً من تحديد دالة، استخدم صفيفة2D.إنشاء الدالة التي تتوفر أيضا للصفائف يصل إلى أربعة أبعاد. مثال التعليمة البرمجية التالية يوضح كيفية إنشاء صفيف صفائف التي تحتوي على عناصر مطلوبة أولاً وثم يستخدم Array2D.initلإنشاء المطلوب ثنائي الأبعاد الصفيف.
let arrayOfArrays = [| [| 1.0; 0.0 |]; [|0.0; 1.0 |] |]
let twoDimensionalArray = Array2D.init 2 2 (fun i j -> arrayOfArrays.[i].[j])
صفيفة indexing و slicing بناء الجملة هو supported for arrays لأعلى إلى يصنف 4. When you specify an فهرس في multiple الأبعاد, you استخدم الفاصلة إلى separate the indices, كـ illustrated في the following تعليمات برمجية مثال.
twoDimensionalArray.[0, 1] <- 1.0
The نوع of a الثاني-dimensional صفيفة هو written خارج كـ <type>[,] (for مثال, int[,], double[,]), و the نوع of a three-dimensional صفيفة هو written كـ <type>[,,], و so تشغيل for arrays of higher الأبعاد.
فقط a subset of the دالات متوفر for واحد-dimensional arrays هو also متوفر for multidimensional arrays. لمزيد من المعلومات، راجع الوحدة النمطية Collections.Array (F #), الوحدة النمطية Collections.Array2D (F #), الوحدة النمطية Collections.Array3D (F #) و الوحدة النمطية Collections.Array4D (F #).
منطقي دالات تشغيل Arrays
الدالات صفيفة.موجود و صفيفة.exists2 باختبار عناصر في صفائف واحد أو الثاني، على التوالي. تأخذ دالة اختبار هذه الدالات وإرجاع trueإذا كان هناك هو عنصر (أو ينشئ ازدواجًا عنصر ل Array.exists2) satهوfies هذا الشرط.
يلي تعليمات برمجية يوضح استخدم Array.existsو Array.exists2. في هذه الأمثلة الجديدة دالات يتم إنشاؤها بواسطة تطبيق واحد فقط من الوسيطات، وفي هذه الحالات، وسيطة دالة.
let allNegative = Array.exists (fun elem -> abs (elem) = elem) >> not
printfn "%A" (allNegative [| -1; -2; -3 |])
printfn "%A" (allNegative [| -10; -1; 5 |])
printfn "%A" (allNegative [| 0 |])
let haveEqualElement = Array.exists2 (fun elem1 elem2 -> elem1 = elem2)
printfn "%A" (haveEqualElement [| 1; 2; 3 |] [| 3; 2; 1|])
إخراج التعليمة البرمجية السابقة هو كما يلي.
true
false
false
true
وبشكل مماثل، اختبار دالة من صفيفة.forall صفيفة إلى تحديد ما إذا كان كل عنصر شرطا منطقية. يقوم التباين من صفيفة.forall2 بتنفيذ نفس الشيء باستخدام منطقي دالة التي تتضمن عناصر صفيفين يساوي الطول. يلي تعليمات برمجية يوضح استخدام هاتين الدالتين.
let allPositive = Array.forall (fun elem -> elem > 0)
printfn "%A" (allPositive [| 0; 1; 2; 3 |])
printfn "%A" (allPositive [| 1; 2; 3 |])
let allEqual = Array.forall2 (fun elem1 elem2 -> elem1 = elem2)
printfn "%A" (allEqual [| 1; 2 |] [| 1; 2 |])
printfn "%A" (allEqual [| 1; 2 |] [| 2; 1 |])
الإخراج لهذه الأمثلة هو كما يلي.
false
true
true
false
يتم الآن البحث في الصفيف
صفيفة.بحث تأخذ دالة منطقية وإرجاع العنصر أول الذي تقوم الدالة بإرجاع true، أو raهوes KeyNotFoundExceptionفي حالة عدم وجود عنصر satهوfies هذا الشرط هو العثور على. صفيفة.findIndex هو مثل Array.find، إلا أن تقوم بإرجاع رقم فهرس العنصر بدلاً من العنصر نفسه.
يلي تعليمات برمجية يستخدم Array.findو Array.findIndexلتحديد رقم الذي هو كل من المربع كلياً ومكعب كلياً.
let arrayA = [| 2 .. 100 |]
let delta = 1.0e-10
let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
let element = Array.find (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrayA
let index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrayA
printfn "The first element that is both a square and a cube is %d and its index is %d." element index
الإخراج هو كما يلي.
The first element that is both a square and a cube is 64 and its index is 62.
صفيفة.tryFind هو مثل Array.find، إلا أن ناتجها هو على نوع خيار، وترجع Noneفي حالة عدم وجود عنصر هو العثور على. Array.tryFindيجب أن يتم استخدام بدلاً منArray.findإذا لم تكن تعرف ما إذا كان هناك عنصر مطابق هو في الصفيف. وبشكل مماثل، من صفيفة.tryFindIndex هو مثل من صفيفة.findIndex إلا أن اكتب خيار هو القيمة الإرجاع. إذا تم العثور على لا يوجد عنصر، فالخيار هو None.
يلي تعليمات برمجية يوضح استخدم Array.tryFind. وهذا تعليمات برمجية يعتمد تشغيل السابق تعليمات برمجية.
let lookForCubeAndSquare array1 =
let result = Array.tryFind (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1
match result with
| Some x -> printfn "Found an element: %d" x
| None -> printfn "Failed to find a matching element."
lookForCubeAndSquare [| 1 .. 10 |]
lookForCubeAndSquare [| 100 .. 1000 |]
الإخراج هو كما يلي.
Found an element: 1
Found an element: 729
استخدم صفيفة.tryPick عندما تحتاج إلى تحويل عنصر بالإضافة إلى العثور عليه. النتيجة هو العنصر أول الذي تقوم دالة بإرجاع العنصر محولة كقيمة خيار، أو Noneفي حالة عدم وجود عنصر مثل هو العثور على.
يلي تعليمات برمجية يظهر استخدم Array.tryPick. في هذه الحالة، بدلاً من تعبير lambda، دالات المساعدة المحلية عدة المعرفة إلى تبسيط التعليمة البرمجية.
let findPerfectSquareAndCube array1 =
// intFunction : (float -> float) -> int -> int
// Allows the use of a floating point function with integers.
let intFunction function1 number = int (round (function1 (float number)))
let cubeRoot x = System.Math.Pow(x, 1.0/3.0)
// testElement: int -> (int * int * int) option
// Test an element to see whether it is a perfect square and a perfect
// cube, and, if so, return the element, square root, and cube root
// as an option value. Otherwise, return None.
let testElement elem =
if isPerfectSquare elem && isPerfectCube elem then
Some(elem, intFunction sqrt elem, intFunction cubeRoot elem)
else None
match Array.tryPick testElement array1 with
| Some (n, sqrt, cuberoot) -> printfn "Found an element %d with square root %d and cube root %d." n sqrt cuberoot
| None -> printfn "Did not find an element that is both a perfect square and a perfect cube."
findPerfectSquareAndCube [| 1 .. 10 |]
findPerfectSquareAndCube [| 2 .. 100 |]
findPerfectSquareAndCube [| 100 .. 1000 |]
findPerfectSquareAndCube [| 1000 .. 10000 |]
الإخراج هو كما يلي.
Found an element 1 with square root 1 and cube root 1.
Found an element 64 with square root 8 and cube root 4.
Found an element 729 with square root 27 and cube root 9.
Found an element 4096 with square root 64 and cube root 16.
تنفيذ حسابات تشغيل الصفيف
صفيفة.average دالة إرجاع المتوسط لكل عنصر في صفيفة. وهي محدودة إلى أنواع العناصر التي تدعم دقة قسمة عدد صحيح، والتي تشمل عائم أشر أنواع والأنواع غير المتكاملة. صفيفة.averageBy الدالة بإرجاع متوسط نتائج استدعاء دالة تشغيل كل عنصر. صفيفة نوع المتكاملة، يمكنك استخدام Array.averageByووجود دالة تحويل كل عنصر إلى فاصلة عائمة أشر النوع لحساب.
استخدم صفيفة.أقصى أو صفيفة.أدنى إلى الحصول على عنصر أقصى أو أدنى، إذا كان معتمداً من نوع العنصر. وبنفس الطريقة، يسمح صفيفة.maxBy و صفيفة.minBy لإحدى الدالات لتنفيذها أولاً، ربما التحويل إلى نوع يعتمد المقارنة.
صفيفة.جمع بإضافة عناصر صفيفة، ومكالمات صفيفة.sumBy دالة تشغيل كل عنصر وإضافة نتائج معا.
إلى تنفيذ دالة تشغيل كل عنصر في صفيفة بدون sإلىring قيم الإرجاع، استخدم من صفيفة.iter. تتضمن دالة الثاني استخدام صفائف متساوية الطول، صفيفة.iter2 . إذا كنت بحاجة أيضا إلى الإبقاء تشغيل صفيفة من نتائج دالة، استخدم صفيفة.مخطط أو صفيفة.مخطط2 ، التي تعمل تشغيل صفيفةين دفعة واحدة.
تباينات من صفيفة.iteri و صفيفة.iteri2 السماح فهرس العنصر أن يتضمنها احتساب؛ نفس الشيء هو صحيح بالنسبة صفيفة.mapi و صفيفة.mapi2 .
الدالات صفيفة.fold صفيفة.foldBack، صفيفة.reduce ، صفيفة.reduceBack ، صفيفة.مسح ضوئي و صفيفة.scanBack بتنفيذ الخوارزميات التي تتضمن الجميع العناصر من الصفيف. Similarly, the variations صفيفة.fold2 و صفيفة.foldBack2 perform computations تشغيل الثاني arrays.
These دالات for performing computations correspond إلى the دالات of the same اسم في the قائمة وحدة نمطية?. For usage أمثلة, see قوائم (F#).
Modifying Arrays
صفيفة.التعيين بتعيين عنصر إلى القيمة محددة. صفيفة.fill بتعيين نطاق من العناصر في صفيفة إلى القيمة محددة. يلي تعليمات برمجية توفير مثال Array.fill.
let arrayFill1 = [| 1 .. 25 |]
Array.fill arrayFill1 2 20 0
printfn "%A" arrayFill1
الإخراج هو كما يلي.
[|1; 2; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 23; 24; 25|]
يمكنك استخدم صفيفة.blit لنسخ القسم الفرعي ضمن القسم الخاص بالصفيف واحد إلى آخر في صفيفة.
تحويل إلى و من أنواع غير ذلك
صفيفة.ofList بإنشاء صفيفة من قائمة. صفيفة.ofSeq بإنشاء صفيفة من تسلسل. صفيفة.toList من صفيفة.toSeq تحويل لهذه المجموعة الغير ذلك أنواع من نوع الصفيف.
فرز الصفيف
من صفيفة.فرز استخدام إلى فرز صفيفة باستخدام دالة مقارنة عامة. استخدام من صفيفة.sortBy إلى قم بتحديد دالة التي تنشئ القيمة الإشارة إلى كعلي مفتاح ، إلى الفرز باستخدام دالة مقارنة عامة تشغيل المفتاح. استخدم من صفيفة.sortWith إذا أردت إلى توفير دالة مقارنة cusإلىm. Array.sort,Array.sortBy، وArray.sortWithالجميع بإرجاع صفيفة الحروف كـ الصفيفة الجديد. تباينات صفيفة.sortInPlace و صفيفة.sortInPlaceBy صفيفة.sortInPlaceWith تعديل الصفيف موجود بدلاً من إرجاع جديد واحد.
صفائف و المجموعات عن
الدالات صفيفة.zip و صفيفة.unzip تحويل صفائف أزواج المجموعة إلى المجموعات عن صفائف والعكس بالعكس. صفيفة.zip3 و من صفيفة.unzip3 تتشابه مع إلا أن تعمل مع المجموعات عن ثلاثة عناصر أو المجموعات عن من الصفائف الثلاثة.
Computatiتشغيلs تشغيل الصفيف متوازي
يتضمن وحدة نمطية من صفيفة.متوازى دالات لتنفيذ حسابات متوازي تشغيل صفائف. Th هو وحدة نمطية? هو غير متاحة في التطبيقات التي تستهدف إصدارات.NET Framework السابقة للإصدار الرابع.