【问题标题】:Is there a way to group_by with_index in Crystal?有没有办法在 Crystal 中通过 with_index 进行分组?
【发布时间】:2018-07-23 08:47:46
【问题描述】:

所以我有这个(排序良好的)数组。

有时我需要数组中的所有元素。但有时我需要将所有偶数索引成员和所有奇数索引成员放在一起。再说一次,有时我需要将它分成三组,一组中的索引为 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类型就得到元素的索引吗?

【问题讨论】:

    标签: crystal-lang


    【解决方案1】:

    你也可以这样做:

    arr = ['a', 'b', 'c', 'd', 'e']
    i = 0
    puts arr.group_by { |x| i += 1; i % 1 }
    i = 0
    puts arr.group_by { |x| i += 1; i % 2 }
    i = 0
    puts arr.group_by { |x| i += 1; i % 3 }
    

    【讨论】:

      【解决方案2】:

      除了 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-15
        • 2019-03-04
        • 2015-11-29
        • 2016-02-13
        • 2019-10-22
        • 1970-01-01
        • 2021-09-21
        • 2011-02-26
        相关资源
        最近更新 更多