Rails:循环比较两个数组并将匹配推送到新数组

时间:2015-03-23 22:54:43

标签: ruby-on-rails ruby arrays comparison

我有两个阵列需要互相检查。找到匹配项后,我需要取消设置第一个数组的值并将该值推送到新数组。

以下是一个例子:

First Array import_data

["mario", "blue", "SGC", "CJ672PA0"], 
["solid snake", "green", "NID", "VI6965KD"], 
["samus", "maroon", "TRUST", "DNYU6539"], 
["deckard cain", "purple", "JAFA", "SJW252MZ"],
["wedge", "yellow", "WALTER", "UJ28NVM1"]

第二个数组current_data

["gordon", "orange", "DRONE", "OGJR8C0D"], 
["samus", "black", "TRUST", "DNYU6539"], 
["commander shepard", "red", "WHX", "TH985OI3"]

请注意,“samus”出现在两个数组中,但所有数据都相同,但颜色有所变化。

我的意图是循环遍历import_data并检查数组中每个项目的最后一个索引(8位“id”)并将其与current_data进行比较。每次找到“匹配”时(基于8位“id”),我想将该项目推送到新的数组update_data,然后我希望unset匹配import_data 1}}数组。

问题是两个数组都有不同的长度。因此,只要我的循环超出了一个项目的长度,它就不能再检查导致错误的索引。

我的代码基本上是这样的:

import_data.each_with_index do |data, index|
  if data[3] == current_data[index].id
    # @update_data << somehow push all of the data
  end
end

这不起作用的原因是因为import_data的长度比current_data的长度长。这会导致错误:

“nil的未定义方法`id':NilClass”

理想情况下,最终结果如下:

“samus”已从import_data数组中移除并推送到update_data数组

循环后

import_data数组

["mario", "blue", "SGC", "CJ672PA0"], 
["solid snake", "green", "NID", "VI6965KD"], 
--- 
["deckard cain", "purple", "JAFA", "SJW252MZ"],
["wedge", "yellow", "WALTER", "UJ28NVM1"]

新填充的数组update_data

 ["samus", "maroon", "TRUST", "DNYU6539"]

2 个答案:

答案 0 :(得分:2)

由于普拉卡什的答案有效,我认为这更为直白:

import_data = [
  ["mario", "blue", "SGC", "CJ672PA0"], 
  ["solid snake", "green", "NID", "VI6965KD"], 
  ["samus", "maroon", "TRUST", "DNYU6539"], 
  ["deckard cain", "purple", "JAFA", "SJW252MZ"],
  ["wedge", "yellow", "WALTER", "UJ28NVM1"]
]
current_data = [
  ["gordon", "orange", "DRONE", "OGJR8C0D"], 
  ["samus", "black", "TRUST", "DNYU6539"], 
  ["commander shepard", "red", "WHX", "TH985OI3"]
]

current_ids = current_data.map {|c| c[3]}

update_data = import_data.inject([]) do |result, data|
  result << import_data.delete(data) if current_ids.include?(data[3])
  result
end

跑完后你得到:

update_data = [
  ["samus", "maroon", "TRUST", "DNYU6539"]
]
import_data = [
  ["mario", "blue", "SGC", "CJ672PA0"], 
  ["solid snake", "green", "NID", "VI6965KD"], 
  ["deckard cain", "purple", "JAFA", "SJW252MZ"],
  ["wedge", "yellow", "WALTER", "UJ28NVM1"]
]

我希望它有所帮助。

答案 1 :(得分:1)

实现目标的一种方法:

import_data = [ 
                ["mario", "blue", "SGC", "CJ672PA0"], 
                ["solid snake", "green", "NID", "VI6965KD"], 
                ["samus", "maroon", "TRUST", "DNYU6539"], 
                ["deckard cain", "purple", "JAFA", "SJW252MZ"],
                ["wedge", "yellow", "WALTER", "UJ28NVM1"]
              ]

current_data = [
                 ["gordon", "orange", "DRONE", "OGJR8C0D"], 
                 ["samus", "black", "TRUST", "DNYU6539"], 
                 ["commander shepard", "red", "WHX", "TH985OI3"]
                ]

找到两个阵列的键:

import_data_keys = import_data.map { |x| x[3] }
=> ["CJ672PA0", "VI6965KD", "DNYU6539", "SJW252MZ", "UJ28NVM1"]
current_data_keys = current_data.map { |x| x[3] }
=> ["OGJR8C0D", "DNYU6539", "TH985OI3"]

通过交叉这两个数组找到公共密钥:

common_keys = import_data_keys & current_data_keys
=> ["DNYU6539"]

使用common_keysimport_data删除并推送到update_data

common_keys.each do |key|
  import_data.each_with_index do |data, index|
    if data[3] == key
      update_data << import_data[index]
      import_data.delete_at(index)
      break
    end
  end
end

注意:break语句用于在找到并处理元素后停止该迭代。