你可以在30秒或更短时间内收集有用的F#代码片段。
- 使用 Ctrl + F 或者 command + F 来查找代码片段。
- 代码片段基于 F#,如果你还不熟悉可以在这里学习。
- 代码片段转译自 little-java-functions
详细信息
chunk
concat
countOccurrences
deepFlatten
difference
differenceWith
distinctValuesOfArray
dropElements
dropRight
everyNth
filterNonUnique
flatten
flattenDepth
groupBy
head
initial
initializeArrayWithRange
initializeArrayWithValues
intersection
isSorted
join
nthElement
pick
reducedFilter
remove
sample
sampleSize
shuffle
similarity
sortedIndex
symmetricDifference
tail
take
takeRight
union
without
zip
zipObject
将数组分割成特定大小的小数组。
let chunk numbers size = numbers |> Array.chunkBySize size
将两个数组合并为一个数组。
let concat first second = Array.concat [first; second]
计算数组中某个值出现的次数。
使用 Array.filter
计算等于指定值的值的总数。
let countOccurrences numbers value = numbers |> ((Array.filter ((=) value)) >> Array.length)
数组扁平化,需要将各元素装箱为 obj
。
使用递归实现,以及 Computation Expression
简化表达。
let rec deepFlatten (input: obj array) =
[| for element in input do
let t = element.GetType()
if t.IsArray then
yield! deepFlatten (element :?> obj array)
else
yield element |]
返回两个数组之间的差异。
使用 Array.except
实现。
let difference first second = Array.except second first
从比较器函数不返回true的数组中筛选出所有值,将comparator(比较器)作为函数参数传入。
使用 Array.filter
和 Array.exists
查找相应的值。
let differenceWith first second comparator =
first
|> Array.filter (fun a -> second |> Array.exists (fun b -> comparator a b) |> not)
返回数组的所有不同值。
使用 Array.distinct
去除所有重复的值。
let distinctValuesOfArray elements = elements |> Array.distinct
移除数组中的元素,直到传递的函数返回true为止。返回数组中的其余元素。
使用 Array.skipWhile
实现。
let dropElements elements condition = elements |> Array.skipWhile condition
返回一个新数组,从右边移除n个元素。
检查n是否短于给定的数组,返回相应的数组切片或空数组,使用 Option
实现 null
安全。
let dropRight elements n =
match n < 0 with
| true -> None
| false -> let arrayLength = Array.length elements
match n < arrayLength with
| true -> Some elements.[.. (arrayLength - n - 1)]
| false -> Some [||]
返回数组中的每个第n个元素。
使用 Array.indexed
创建一个包含索引的新数组,通过索引需要满足的的条件筛选原数组的值。
let everyNth elements nth =
[| for index, element in elements |> Array.indexed do
if index % nth = nth - 1 then
yield element |]
查找数组中元素的索引,在不存在元素的情况下返回-1。
使用 Array.tryFindIndex
安全查找数组中元素的索引。
let indexOf elements el = elements |> Array.tryFindIndex ((=) el)
|> function | Some x -> x | None -> -1
查找数组中元素的最后索引,在不存在元素的情况下返回-1。
使用 Array.tryFindIndexBack
安全查找数组中元素的索引。
let lastIndexOf elements el = elements |> Array.tryFindIndexBack ((=) el)
|> function | Some x -> x | None -> -1
筛选出数组中的非唯一值。
let filterNonUnique elements = elements |> Array.groupBy id
|> Array.filter (snd >> Array.length >> (=) 1)
|> Array.map fst
使数组扁平。
let flatten (elements: obj array) =
[| for element in elements do
let t = element.GetType()
if t.IsArray then
yield! (element :?> obj array)
else
yield element |]
将数组压平到指定的深度。
let rec flattenDepth (elements: obj array) depth =
match depth with
| 0 -> elements
| _ -> [| for element in elements do
let t = element.GetType()
if t.IsArray then
yield! flattenDepth (element :?> obj array) (depth - 1)
else
yield element |]
根据给定函数对数组元素进行分组。
使用 Arrays.groupBy
分组。
let groupBy elements func = elements |> Array.groupBy func
返回数组中除去最后一个的所有元素。
直接使用切片返回除最后一个之外的所有元素。
let initial (elements: 'a array) = elements.[..(elements.Length - 2)]
初始化一个数组,该数组包含在指定范围内的数字,传入 start
和 end
。
let initializeArrayWithRange ``end`` start = [| start .. ``end`` |]
使用指定的值初始化并填充数组。
let initializeArrayWithValues n value = [| for _ in 1 .. n -> value |]
返回两个数组中存在的元素列表。
在 a 上使用 Array.filter
来筛选包含在 b 中的值。
let intersection first second = first |> Array.filter (fun x -> set second |> Set.contains x)
如果数组按升序排序,则返回 1
,如果数组按降序排序,返回 -1
,如果没有排序,则返回 0
。
Naive implementation,将会改进。
let isSorted arr =
match arr = (arr |> Array.sort), arr = (arr |> Array.sortDescending) with
| true, _ -> 1
| _, true -> -1
| _, _ -> 0
将数组的所有元素连接到字符串中,并返回此字符串。
使用 String.concat
将元素组合成字符串。
let join arr separator ``end`` =
arr |> Array.map string
|> String.concat separator
|> (fun x -> x + ``end``)
返回数组的第n个元素。
let nthElement (arr: 'a array) n =
match n > 0 with
| true -> arr.[n - 1]
| false -> arr.[arr.Length + n]
从对象中选择与给定键对应的键值对。
使用 Map
将所有的 seq<'a * 'b>
转换为Map。
let pick obj arr =
arr |> Array.filter (fun x -> obj |> Map.containsKey x)
|> Array.map (fun x -> x, obj.[x])
|> Map
根据条件筛选对象数组,同时筛选出未指定的键。
使用 Array.filter
根据谓词 fn
过滤数组,以便返回条件为真的对象。
对于每个过滤的Map对象,创建一个新的Map,其中包含 keys
中的键。最后,将Map对象收集到一个数组中。
let reducedFilter data keys fn =
data
|> Array.filter fn
|> Array.map (fun el -> keys |> Array.filter (fun x -> el |> Map.containsKey x)
|> Array.map (fun x -> x, el.[x])
|> Map)
从数组中返回一个随机元素。
使用 Random().NextDouble()
生成一个随机数,然后将它乘以数组的 length
,然后使用 floor >> int
获得一个最近的整数,该方法也适用于字符串。
let sample (arr: 'a array) = let rnd = Random()
arr.[(rnd.NextDouble() * (float arr.Length)) |> (floor >> int)]
从 array
到 array
大小的唯一键获取 n
个随机元素。
let sampleSize input n =
let rnd = Random()
let rec inner (arr: 'a array) m =
match m with
| 0 -> arr
| _ -> let i = (rnd.NextDouble() * (float m)) |> (floor >> int)
let tmp = arr.[i]
arr.[i] <- arr.[m]
arr.[m] <- tmp
inner arr (m - 1)
let copy = input |> Array.copy
let length = input.Length
if n > length then (inner copy (length - 1)) else (inner copy n) |> Array.take n
将数组值的顺序随机化,返回一个新数组。
根据 Fisher-Yates 算法 重新排序数组的元素。
let shuffle input =
let rnd = Random()
let rec inner (arr: 'a array) m =
match m with
| 0 -> arr
| _ -> let i = (rnd.NextDouble() * (float m)) |> (floor >> int)
let tmp = arr.[i]
arr.[i] <- arr.[m]
arr.[m] <- tmp
inner arr (m - 1)
let copy = input |> Array.copy
let length = input.Length
inner copy (length - 1)
返回出现在两个数组中的元素数组。
与 intersection
实现一致,因为 F# 的函数是自动泛化
的不需要专门实现同一函数的泛型版本。
let similarity first second = first |> Array.filter (fun x -> set second |> Set.contains x)
返回值应该插入到数组中的最低索引,以保持其排序顺序。
检查数组是否按降序(松散地)排序。 建立索引的数组并使用 Array.filter
来找到元素应该被插入的合适的索引。
let sortedIndex (arr: 'a array) el =
let isDescending = arr.[0] > arr.[1]
[| 0 .. arr.Length - 1 |]
|> Array.filter (fun index -> if isDescending then el >= arr.[index] else el <= arr.[index])
|> Array.tryHead
|> function | Some x -> x | None -> arr.Length
返回两个数组之间的对称差异。
从每个数组中创建一个 Set
,然后使用 Array.filter
来保持其他值不包含的值。最后,连接两个数组并创建一个新数组并返回。
let symmericDifference first second =
[| first |> Array.filter (fun x -> set second |> Set.contains x);
second |> Array.filter (fun x -> set first |> Set.contains x) |]
|> Array.concat
返回数组中除第一个元素外的所有元素。
let tail arr = arr |> Array.tail
返回一个从开头删除n个元素的数组。
let take arr n = arr |> Array.skip n
返回从末尾移除n个元素的数组。
使用切片语法。
let takeRight (arr: 'a array) n = arr.[(arr.Length - n)..]
返回两个数组中任何一个中存在的每个元素一次。
let union first second = set first |> Set.union (set second) |> Array.ofSeq
筛选出具有指定值之一的数组的元素。
let without arr elements = arr |> Array.filter (fun x -> set elements |> Set.contains x |> not)
根据原始数组中的位置创建元素数组。
let zip (arrays: 'a array array) =
let maxIndex = arrays |> Array.map (fun x -> x.Length)
|> Array.max
[| for index in [0 .. maxIndex - 1] do
yield arrays |> Array.map (fun x -> if index < x.Length then Some x.[index] else None) |]
给定有效的属性标识符数组和值数组,返回将属性与值关联的对象。
let zipObject props values =
props
|> Array.mapi (fun index prop -> prop, if index < (values |> Array.length) then Some values.[index] else None)
|> Map
返回两个或两个以上数字的平均值。
let inline average (arr: ^a array when ^a : (static member (+) : ^a * ^a -> ^a)) = arr |> Array.average
计算一系列数字的最大公约数(gcd)。
使用 Array.reduce
和 GCD(使用递归公式)计算一组数字的最大公约数。
let gcd numbers =
let rec inner a b =
match b = 0 with
| true -> a
| false -> inner b (a % b)
numbers |> Array.reduce inner
计算数字数组的最低公共倍数(LCM)。
使用 Array.reduce
和 LCM公式(使用递归)来计算数字数组的最低公共倍数。
let lcm numbers =
let rec gcd' a b =
match b = 0 with
| true -> a
| false -> gcd' b (a % b)
let lcm' a b = (a * b) / (gcd' a b)
numbers |> Array.reduce lcm'
查找大于或等于该值的下一个幂。
let findNextPositivePowerOfTwo value = 1 <<< Convert.ToString(value - 1, 2).Length
检查数字是否是偶数。
let isEven value = (value &&& 1) = 0
检查一个值是2的正幂。
let isPowerOfTwo value = (value > 0) && ((value &&& (~~~value + 1)) = value)
生成一个介于 Int32.MinValue
和 Int32.MaxValue
之间的随机数。
let generateRandomInt () =
let rnd = Random()
rnd.Next(Int32.MinValue, Int32.MaxValue)