我有一个从数据库返回的数组数组,并希望确保它们的长度始终相同。当他们不是我想推零时,使它们适当长度,但也保持指数的完整性。
大部分时间看起来都像
array = [["apple", "blueberries", "banana", "kiwi"], ["20.15", "13.50", "22.10", "10.50"], ["10", "12", "26", "34"]]
我最终会打电话给each_with_index
,并且需要他们匹配ie。苹果,20.15,10在一张桌子里。
每隔一段时间,数组中就会丢失一两个元素,我想将零推入其位置。
array2 = [["apple", "blueberries", "banana", "kiwi"], ["20.15", "22.10"], ["10", "12", "26", "34"]]
我尝试过像
这样的事情array2.each {|f| f.push(0) until f.length === 4}
=>[["apple", "blueberries", "banana", "kiwi"], ["20.15", "13.50", 0, 0], ["10", "12", "26", "34"]]
但是零将被推到数组的末尾 - 理想情况下输出将是
=>[["apple", "blueberries", "banana", "kiwi"], ["20.15", 0, "13.50", 0], ["10", "12", "26", "34"]]
答案 0 :(得分:0)
在这里做一些假设:
array2
总是大小为4。array2
只会丢失1或2个元素。array3 = case array2.size when 4 array2 when 3 array2 + [0] when 2 array2.zip([0, 0]).flatten else raise "problem" end
答案 1 :(得分:0)
我讨厌打破它,但编程对孩子来说不是一件容易的事,正如非程序员有时想象的那样。您的情况需要创建一个单独的类,可能是Array的子类。像这样:
class GreenGrocer < Array
end
现在我们可以想象重新定义GreenGrocer.new
公共类方法,以确保每个GreenGrocer
实例都缺少用零修补的元素,如下所示:
class GreenGrocer # reopening the class we defined earlier
class << self
def new array
produce, float_array, int_array = array.reduce( &:zip ).map( &:flatten ).transpose
super [ produce, float_array.map { |e| e or 0.0 }, int_array.map { |e| e or 0 } ]
end
def [] *elements; new elements end
end
end
# so we can call
g = GreenGrocer.new( array2 )
# or
g = GreenGrocer[ *array2 ]
但为什么要这么麻烦?只需制作一个#to_table
方法,可以根据需要将不完整的数据结构转换为表格,并在流程中填充缺失的数据点。所以我们定义:
class LazierGreenGrocer < Array
def to_table
reduce( &:zip ).map( &:flatten ).map { |e| e.map { |e| e || 0 } }
end
end
lazier_g = LazierGreenGrocer.new( array2 ) # not eager to do work upon initialization
lazier_g.to_table # does the required work as #to_table is called
我就是这样做的。由于我不知道您想要输出哪种确切的表格,因此您可能需要相应地修改我的#to_table
方法。