根据匹配的ID删除数组中的重复项.轨道

Tin*_*ner 1 ruby arrays

所以我有一个.csv我导入数组的文件.他们都是逗号分开的,所以我已经为他们做了一个很好的阵列.

现在我正在尝试找到匹配id的记录,这样我就可以删除重复项,只保留最后遇到的内容.ID例如使用.

我已导入到数组但由于某种原因我无法获得像uniq这样的工具来显示新的唯一列表,即使我在它上面执行.length,它返回正确的行数.

任何帮助将不胜感激.

    lines = []
    i = 0

    file = File.open("./properties.csv", "r")

    elements = Array[]
    element2 = Array[]
    output = Array[]

    while (line = file.gets)
        i += 1
      # use split to break array up using commas
        arr = line.split(',')
        elements.push({ id: arr[0], streetAddress: arr[1], town: arr[2], valuationDate: arr[3], value: arr[4] })
    end

    file.close

    # Loop through array and sort nicely
     element2 = elements.group_by { |c| c[:id] }.values.select { |elements| elements.size > 1 }


    output = (element2.uniq)
    puts output

    puts element2.length
Run Code Online (Sandbox Code Playgroud)

样本.CSV文件

ID,Street address,Town,Valuation date,Value
1,1 Northburn RD,WANAKA,1/1/2015,280000
2,1 Mount Ida PL,WANAKA,1/1/2015,280000
3,1 Mount Linton AVE,WANAKA,1/1/2015,780000
1,1 Northburn RD,WANAKA,1/1/2015,330000
2,1 Mount Ida PL,WANAKA,1/1/2015,330000
3,1 Mount Linton AVE,WANAKA,1/1/2015,830000
1,1 Northburn RD,WANAKA,1/1/2016,340000
2,1 Mount Ida PL,WANAKA,1/1/2016,340000
3,1 Mount Linton AVE,WANAKA,1/1/2016,840000
4,1 Kamahi ST,WANAKA,1/1/2016,215000
5,1 Kapuka LANE,WANAKA,1/1/2016,209000
6,1 Mohua MEWS,WANAKA,1/1/2016,620000
7,1 Kakapo CT,WANAKA,1/1/2016,490000
8,1 Mt Gold PL,WANAKA,1/1/2016,1320000
9,1 Penrith Park DR,WANAKA,1/1/2016,1310000
Run Code Online (Sandbox Code Playgroud)

Tin*_*ner 5

所以我实际上交换了使用哈希的方法.这似乎自动删除重复并留下最后遇到的记录完好无损?谁能在这里解决一些问题?

    require 'csv'

    element = {}

    CSV.foreach("properties.csv", :headers => true, :header_converters => :symbol) do |row|
        element[row.fields[0]] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
    end

    puts element["1"]

    element.each do |key, value|
        puts key 
        puts value
    end

    puts "#{element.length} records returned" 
Run Code Online (Sandbox Code Playgroud)

要保留第一个匹配元素而不是最后一个,可以在分配值之前进行密钥存在性检查.这可以这样做:

CSV.foreach("properties.csv", :headers => true, :header_converters => :symbol) do |row|
  key = row.fields[0]
  if !element.key?(key)
    element[key] = Hash[row.headers[1..-1].zip(row.fields[1..-1])]
  end
end
Run Code Online (Sandbox Code Playgroud)

也可以这样写得更有效:

CSV.foreach("properties.csv", :headers => true, :header_converters => :symbol) do |row|
  element[row.fields[0]] ||= Hash[row.headers[1..-1].zip(row.fields[1..-1])]
end
Run Code Online (Sandbox Code Playgroud)

请注意,保留密钥的第一个找到记录的这些方法将比保留密钥的最终找到记录的版本执行得更好.这是因为工作回避的,主要是在产生散列值,其与进行slicezip在此代码.