背景
嘿所有,我正在尝试使用外部API,并尝试从网站吸引用户的所有关注者并应用一些排序。
我已经重构了很多代码,但是有一部分给了我一个非常艰难的时间。我相信有一种比我所包含的更容易实现这一点的方式,并且非常感谢以更加雄辩的方式做到这一点的任何提示。
我的目标很简单。我想将哈希数组的数组(我希望这是解释它的正确方法)合并到一个哈希数组中。
问题描述:
我有一个名为f_collections
的数组,它有5个元素。每个元素都是一个大小为200的数组。这些数组的每个子元素都是大约10个键值对的散列。我最好的代表如下:
f_collections = [ collection1, collection2, ..., collection5 ]
collection1 = [ hash1, hash2, ..., hash200]
hash1 = { user_id: 1, user_name: "bob", ...}
我试图将这个多维数组折叠成一个哈希数组。由于有五个集合数组,这意味着结果数组将有1000个元素 - 所有这些元素都是哈希值。
followers = [hash1, hash2, ..., hash1000]
代码(即我不想保留的尝试):
我已经使用非常丑陋的代码片段(见下文),使用嵌套的if语句,块,for循环等等...这件事是一个噩梦,需要阅读和我已经尽力研究如何以更简单的方式做到这一点,我只是无法弄清楚如何做到这一点。我尝试过扁平化,但它似乎无法发挥作用。
我大多只是包含这些代码来表明我已经非常努力地解决了这个问题,虽然是的我解决了它,但必须有更好的方法!
注意:我在下面的代码中将一些变量简化为整数,以使其更具可读性。
for n in 1..5 do
if n < 5
(0..199).each do |j|
if n == 1
nj = j
else
nj = (n - 1) * 200 + j
end
@followers[nj] = @f_collections[n-1].collection[j]
end
else
(0..199).each do |jj|
njj = (4) * 200 + jj
@followers[njj] = @f_collections[n-1].collection[jj]
end
end
end
答案 0 :(得分:1)
哦......所以它不是一个包含哈希集合的数组对象。的种类。让我们再试一次:
flat = f_collection.map do |col|
col.collection
end.flatten
可以缩短(并且更高效):
flat = f_collection.flat_map do |col|
col.collection
end
这是有效的,因为f_collection
数组中的项目是具有collection
属性的对象,而该属性又是一个数组。
所以它是&#34;具有包含散列的数组的数组&#34;
旧答案如下。我把它留在这里是为了记录目的。它基于数据结构是散列数组的假设。
只需使用#flatten
(或#flatten!
,如果您希望这是&#34;内联&#34;)
flat = f_collections.flatten
实施例
sub1 = [{a: 1}, {a: 2}]
sub2 = [{a: 3}, {a: 4}]
collection = [sub1, sub2]
flat = collection.flatten # returns a new collection
puts flat #> [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
# or use the "inplace"/"destructive" version
collection.flatten! # modifies existing collection
puts collection #> [{:a=>1}, {:a=>2}, {:a=>3}, {:a=>4}]
针对现有代码的一些建议:
不要使用for n in 1..5
,请使用Ruby-Style枚举:
["some", "values"].each do |value|
puts value
end
像这样你不需要硬编码数组的长度(5
)(没有意识到你删除了指定这些幻数的变量)。如果要检测最后一次迭代,可以使用each_with_index
:
a = ["some", "home", "rome"]
a.each_with_index do |value, index|
if index == a.length - 1
puts "Last value is #{value}"
else
puts "Values before last: #{value}"
end
end
虽然#flatten
可以解决您的问题,但您可能希望了解DIY解决方案的外观:
def flatten_recursive(collection, target = [])
collection.each do |item|
if item.is_a?(Array)
flatten_recursive(item, target)
else
target << item
end
end
target
end
或迭代解决方案(限于两个级别):
def flatten_iterative(collection)
target = []
collection.each do |sub|
sub.each do |item|
target << item
end
end
target
end