Swift 感受“爱”;“需要速度”;使用reduce(into::)对三元组元素集的封闭数组中的元素进行计数
鉴于这个三元组的示例数组,实际数组将是非常大的数据集,因此“需要速度”: 在保留三元组的同时,使用swift查找此类型数组中每个元素的计数,因此输出如下所示:Swift 感受“爱”;“需要速度”;使用reduce(into::)对三元组元素集的封闭数组中的元素进行计数,swift,block,reduce,counting,Swift,Block,Reduce,Counting,鉴于这个三元组的示例数组,实际数组将是非常大的数据集,因此“需要速度”: 在保留三元组的同时,使用swift查找此类型数组中每个元素的计数,因此输出如下所示: let keyValuePairs =[ [[0: 1], [1: 3], [2: 5]], [[2: 5], [1: 3], [3: 6]], [[1: 3], [4: 2], [3: 6]], [[3: 6], [4: 2], [5: 4]], [[6: 1], [7: 3], [8: 5]], [[8: 5]
let keyValuePairs =[
[[0: 1], [1: 3], [2: 5]],
[[2: 5], [1: 3], [3: 6]],
[[1: 3], [4: 2], [3: 6]],
[[3: 6], [4: 2], [5: 4]],
[[6: 1], [7: 3], [8: 5]],
[[8: 5], [7: 3], [9: 6]],
[[7: 3], [10: 2], [9: 6]],
[[9: 6], [10: 2], [11: 4]],
// etc. ...
]
我只是建议“减少(到)”,因为这感觉是可能的,但它可能完全是其他更好/更快/更强的东西
(不必保留三元组集合的顺序,但必须保留三元组内元素的顺序::例如,第一个和第二个集合需要保持[[0:x]、[1:x]、[2:x]、[[2:x]、[1:x]、[3:x]],或者作为示例,顺序可以是[[2:x]、[1:x]、[3:x]、[0:x]、[1:x]、[2:x]]
到目前为止,我已经能够使用下面的代码生成正确的组织,感觉这可以通过reduce(into:u:)解决,但我无法正确地“计算”元素。我将代码保留在其中,它不能正确计算,显然是因为每次都初始化了,但我想展示我到目前为止所拥有的:
let keyValuePairs = usedIndicies2.reduce(into: [[[UInt32:Int]]]()) { (array, entry) in
var dict0:[UInt32:Int] = [UInt32:Int]()
var dict1:[UInt32:Int] = [UInt32:Int]()
var dict2:[UInt32:Int] = [UInt32:Int]()
dict0[entry[0], default: 0] += 1
dict1[entry[1], default: 0] += 1
dict2[entry[2], default: 0] += 1
var array012:[[UInt32:Int]] = [[UInt32:Int]]()
array012.append(dict0)
array012.append(dict1)
array012.append(dict2)
array.append(array012)
}
print("keyValuePairs:",keyValuePairs)
此部分工作代码的输出如下所示:
let keyValuePairs** = [
[[0: 1], [1: 1], [2: 1]],
[[2: 1], [1: 1], [3: 1]],
[[1: 1], [4: 1], [3: 1]],
[[3: 1], [4: 1], [5: 1]],
[[6: 1], [7: 1], [8: 1]],
[[8: 1], [7: 1], [9: 1]],
[[7: 1], [10: 1], [9: 1]],
[[9: 1], [10: 1], [11: 1]],
// etc...
]
非常感谢您的见解两个步骤:
let original = [[0, 1, 2], [2, 1, 3], [1, 4, 3], [3, 4, 5]]
// step 1
var histo = [Int:Int]()
original.flatMap {$0}.forEach {histo[$0, default:0] += 1}
// step 2
let output = original.map {array in array.map {i in (item:i, count:histo[i]!)}}
结果:
[[(item: 0, count: 1), (item: 1, count: 3), (item: 2, count: 2)],
[(item: 2, count: 2), (item: 1, count: 3), (item: 3, count: 3)],
[(item: 1, count: 3), (item: 4, count: 2), (item: 3, count: 3)],
[(item: 3, count: 3), (item: 4, count: 2), (item: 5, count: 1)]]
这是正确的。实际上似乎很简单。首先,将数组展平,只需为所有值制作一个普通的直方图(计数)(这是一条直线)。然后返回原始数组并将其映射到成对数组中。我希望在一个块内完成此操作,因为这似乎是reduce能做得最好的,直方图确实很容易,但在一个块内保持三元组顺序很困难。我真的不知道“在一个块中”是什么或者,如果您愿意,尽可能少的循环/函数/分支,它感觉像reduce(into):可以用很少的“额外”来实现这一点干预,我当然可能是错的。@LeoDabus是的,我调整的重点是,我看不到只有一个条目的字典的值。只是没有目的的大量开销。感谢这个两步过程,而且可能确实不可能在一个简化中完成(into:block。我觉得这是可能的,所以我会等着看是否有人能展示一个reduce(into:function)(或者什么函数),速度方面会更好,因为我会在海量数据集上使用它。我会在我的问题标题“reduce(into)”中添加“对速度的需求”:当然,这很公平。在上面的代码中,每次我都有一个左大括号,这就是一个循环。但请注意,我不知道如何减少循环的数量,因为在开始处理问题时,您必须已经知道直方图计数。如果不知道,那么每次遇到已使用的元素和nge所有提到的元素的数量都是指数级的。因此,我认为我的方法是快速方法,而你的
reduce(into:)
spec是一个麻烦(也称为x-y问题)。
[[(item: 0, count: 1), (item: 1, count: 3), (item: 2, count: 2)],
[(item: 2, count: 2), (item: 1, count: 3), (item: 3, count: 3)],
[(item: 1, count: 3), (item: 4, count: 2), (item: 3, count: 3)],
[(item: 3, count: 3), (item: 4, count: 2), (item: 5, count: 1)]]