通过比较两个相邻的元素分组阵列 [英] Grouping an array by comparing 2 adjacent elements

查看:184
本文介绍了通过比较两个相邻的元素分组阵列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有对象的数组,我想将它们分组基于2个相邻元素的属性之间的差异。该阵列是已经由该属性排序。例如:

I have an array of objects and I would like to group them based on the difference between the attributes of 2 adjacent elements. The array is already sorted by that attribute. For instance:

原始数组:

阵列= [A,B,C,D,E]

a.attribute = 1
b.attribute = 3
c.attribute = 6
d.attribute = 9
e.attribute = 10 

如果我想组的元素,使得两个相邻元素的属性之间的差异大于2小于或等于,结果看起来应该像这样:

If I want to group the elements such that the difference between the attributes of 2 adjacent elements are less or equal than 2, the result should look like so:

END结果

result_array = [[A,B],[C],[D,E]

我有什么

def group_elements_by_difference(array, difference)
    result_array = []
    subgroup = []
    last_element_attribute = array.first.attribute
    array.each do |element|
      if element.attribute <= (last_element_attribute + difference)
        subgroup << element
      else
        #add the subgroup to the result_array
        result_array << subgroup
        subgroup = []
        subgroup << element
      end
      #update last_element_attribute
      last_element_attribute = element.attribute
    end
    result_array << subgroup
end

有一个内置功能的Ruby 1.9.3,如 GROUP_BY ,它可以代替我的 group_elements_by_difference

Is there a built in function in Ruby 1.9.3, such as group_by that could replace my group_elements_by_difference?

推荐答案

继一月德沃夏克的建议,该解决方案使用slice_before和哈希以保持状态:

Following Jan Dvorak's suggestion, this solution uses slice_before and a hash to keep the state:

class GroupByAdjacentDifference < Struct.new(:data)
  def group_by(difference)
    initial = { prev: data.first }

    data.slice_before(initial) do |item, state|
      prev, state[:prev] = state[:prev], item
      value_for(item) - value_for(prev) > difference
    end.to_a
  end

  def value_for(elem)
    elem.attribute
  end
end

require 'rspec/autorun'

describe GroupByAdjacentDifference do

  let(:a) { double("a", attribute: 1) }
  let(:b) { double("b", attribute: 3) }
  let(:c) { double("c", attribute: 6) }
  let(:d) { double("d", attribute: 9) }
  let(:e) { double("e", attribute: 10) }

  let(:data) { [a, b, c, d, e] }
  let(:service) { described_class.new(data) }

  context "#group_by" do
    it "groups data by calculating adjacent difference" do
      expect(service.group_by(2)).to eq([[a, b], [c], [d, e]])
    end
  end
end

这使得

$ ruby group_by_adjacent_difference.rb
.

Finished in 0.0048 seconds
1 example, 0 failures

在替代,局部变量也可以用来保持状态,虽然我觉得有点难以阅读:

In alternative, local variables could also be used to keep state, although I find it a bit harder to read:

class GroupByAdjacentDifference < Struct.new(:data)
  def group_by(difference)
    tmp = data.first

    data.slice_before do |item|
      tmp, prev = item, tmp
      value_for(item) - value_for(prev) > difference
    end.to_a
  end

  def value_for(elem)
    elem.attribute
  end
end

这篇关于通过比较两个相邻的元素分组阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆