假设我们有一对输入数组,或者你喜欢的(键,值)元组列表。什么是优雅和高效的方式来组合指数落在特定区间内的值?例如,如果间隔(或&#39; bin&#39;)大小为10,则0 < x <= 10
的所有索引的值将合并,10 < x <= 20
的索引值也会合并上。我想要:
let interval = 10
let index = [| 6; 12; 18; 24 |]
let value = [| a; b; c; d |]
result = [| a; b + c; d |]
最粗略的方法是使用大量的if,else if语句(索引范围有一个定义的上限)。
我接近了for i = 0 to index.Length do
result.[Math.Floor(index.[i]/10] += value.[Math.Floor(index.[i]/10]
但这是0 <= x < 10
,而不是0 < x <= 10
。
我还尝试假设索引是有序且均匀分布的,
for i = 1 : ( index.Length - 1 ) / valuesPerBin
valueRange = ((i-1)*valuesPerBin + 1) : i*valuesPerBin )
result(i) = sum(value(valueRange))
这很好但是如果每个bin有一个非整数值的话,它会明显中断。
在F#中执行此操作的最佳方法是什么?是否有我想要做的名称或现有功能?
答案 0 :(得分:1)
let interval = 10
let index = [6;12;18;24]
let value =[101;102;103;104]
let intervals = List.map (fun e -> e/interval) index
let keys = List.map2(fun e1 e2 -> (e1,e2)) intervals value
let skeys = Seq.ofList keys
let result = skeys
|>Seq.groupBy (fun p -> fst p)
|>Seq.map (fun p -> snd p)
|>Seq.map(fun s -> Seq.sumBy (fun p -> snd p) s)
结果 将是[ 101; 205; 104 ](作为Seq)。
如果要转换为数组,请应用Seq.toArray。
这是你想要的吗?
答案 1 :(得分:0)
调整要使用的周围代码
0 <= x < 10
代替0 < x <= 10
。在我的情况下,这只是另一个函数的简单定义更改,允许我使用
for i = 0 to index.Length do
result.[Math.Floor(index.[i]/10] += value.[Math.Floor(index.[i]/10]
,这比其他选择更简单,更简洁。