所以我有这个(排序好的)数组。
有时我需要数组中的所有元素。但是有时候我需要所有偶数索引的成员在一起,而所有奇数索引的成员在一起。然后再说一次,有时我需要将它分为三组,一组索引为0、3、6等,然后下一组为1,4,7,最后一组为2,5,8。
这可以通过group_by
并采用索引的模数来完成。亲自看看:
https://play.crystal-lang.org/#/r/4kzj
arr = ['a', 'b', 'c', 'd', 'e']
puts arr.group_by { |x| arr.index(x).not_nil! % 1 } # {0 => ['a', 'b', 'c', 'd', 'e']}
puts arr.group_by { |x| arr.index(x).not_nil! % 2 } # {0 => ['a', 'c', 'e'], 1 => ['b', 'd']}
puts arr.group_by { |x| arr.index(x).not_nil! % 3 } # {0 => ['a', 'd'], 1 => ['b', 'e'], 2 => ['c']}
但是其中的not_nil!
感觉像是代码气味/警告,这是一种更好的方法。
我可以获取元素的索引而不需要查找它并处理Nil类型吗?
答案 0 :(得分:5)
您也可以这样做:
class Application
pg_search_scope :search, against: %i[email full_name id_no company_reg_no id vehicle_reg_no], using: {
tsearch: {
any_word: true
},
trigram: {
only: %i[vehicle_reg_no full_name]
}
}
end
答案 1 :(得分:4)
除了nilable返回类型外,为每个元素调用Array#index
也是非常低效的。这意味着运行时间为O(N²)。
#group_by
用于按值分组,但是您不需要用于分组的值,因为您只想按索引分组。这比包裹#group_by
和#index
一种更有效的解决方案是遍历索引并根据索引对值进行分组:
groups = [[] of Char, [] of Char]
arr.each_index do |i|
groups[i % 2] << arr[i]
end
对此没有特殊的方法,但是实现自己非常简单。
如果不需要所有组,而只需要其中一个,则还可以使用Int32#step
来迭代其他所有索引:
group = [] of Char
2.step(to: arr.size - 1, by: 3) do |i|
group << arr[i]
end