Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Ruby在主集合上循环,处理每个子集合的最干净的方法_Ruby_Loops_Records - Fatal编程技术网

用Ruby在主集合上循环,处理每个子集合的最干净的方法

用Ruby在主集合上循环,处理每个子集合的最干净的方法,ruby,loops,records,Ruby,Loops,Records,这是一种常见的情况,我对解决方案从来都不太满意。您有一组数据,在本例中,只需假设数据库中的行按类别排序 您希望使用每个类别的子集构建一个缓冲区,并在每次类别更改时进行一些处理,然后清除缓冲区。假设这个过程被包装在一堆复杂的逻辑中,您不想复制这些逻辑 有人有更好的设置吗 # category, city data = [ [10, 'citya'], [10, 'cityb'], [11, 'citya'], [11,

这是一种常见的情况,我对解决方案从来都不太满意。您有一组数据,在本例中,只需假设数据库中的行按类别排序

您希望使用每个类别的子集构建一个缓冲区,并在每次类别更改时进行一些处理,然后清除缓冲区。假设这个过程被包装在一堆复杂的逻辑中,您不想复制这些逻辑

有人有更好的设置吗

# category, city
data = [
          [10, 'citya'],
          [10, 'cityb'],
          [11, 'citya'],
          [11, 'cityb'],
          [11, 'citya'],
          [12, 'cityb'],
          [12, 'cityg']
       ]

# do some heavy lifting in here
def process(buf) p buf; end

cur_cat = nil
cur_cat_buf = []
data.each do |r|
  if r[0] != cur_cat
    cur_cat = r[0]
    process(cur_cat_buf) #<-- assume this is conditional, complex
    cur_cat_buf.clear
  end
  cur_cat_buf << r[1]
end
process(cur_cat_buf) #<-- assume the conditional is duplicated...ack.
这是另一种技术,非常糟糕。一团糟,糟透了!始终向前看,检查它是否为零或不同等…呃

cur_cat = data[0][0] if data.length > 0
cur_cat_buf = []
data.each_with_index do |r, i|
  cur_cat_buf << r[1]

  # look ahead
  if data[i+1] == nil or data[i+1][0] != cur_cat
    cur_cat = data[i+1][0] if data[i+1] != nil
    process(cur_cat_buf)
    cur_cat_buf.clear
  end
end
这是另一种选择。当然比上次好

cur_cat = nil
cur_cat_buf = []
for i in 0..(data.length)
  if (r = data[i]) == nil or r[0] != cur_cat
    process(cur_cat_buf)
    break unless r

    cur_cat_buf.clear
    cur_cat = r[0]
  end

  cur_cat_buf << r[1]
end
我想要一个干净、优雅的解决方案。一定有更好的办法

data.group_by(&:first).each_value {|buffer| process(buffer.map &:last) }
或者类似的,但稍微详细一点,但稍微明确一点:

data.group_by { |category_id, city| category_id }.each_value do |pairs| 
  process(pairs.map { |category_id, cities| cities }) 
end

这种代码有一个名字,叫做命令式噩梦。你应该非常非常了解Ruby中的函数编程:map、select、inject、groupby、zip……而且,这个过程函数有点臭。为什么他们的模块之外有逻辑?只是一个假设的例子。假设那里发生了什么事。“是的,完全是老派的命令。”史蒂夫。阅读函数式编程,你会意识到这些年来你一直生活在黑暗中:-而且,如果没有一些你想要得到的示例,那么很难确定解决方案,因为这个问题是主观的和/或过于宽泛的,所以把它作为一个候选问题来结束。提供一个更好的目标,我相信你会得到很多推荐的解决方案。这并不是很好。一步之遥。啊,是的,我没有注意到。这是怎么回事?我的理解是:第一是符号第一的方法。它似乎没有被记录。它被记录了,但不是在数组中,是的,它有点微妙。查看您常用的Ruby文档,但在类符号下。你会发现,在proc中,plus&convert-to/from块就是魔法发生的地方。更详细但更清晰的版本是:data.group_by{category_id,city}category_id}.values。添加了两种方法。谢谢。找到了。这是一个模糊的小特征。
data.group_by { |category_id, city| category_id }.each_value do |pairs| 
  process(pairs.map { |category_id, cities| cities }) 
end