2016-05-12 7 views
1

私は配列にインポートした.csvファイルを持っています。それらはすべてコンマで区切られているので、私は先に進んで、素敵な配列を作った。一致するIDに基づいて配列内の重複を削除します。 Rails

私はIDが一致するレコードを検索しようとしていますので、重複を削除して最後に遭遇したものだけを保持することができます。たとえばIDを使用します。

私は配列にインポートしましたが、何らかの理由でユニークのようなツールを取得できないため、新しいユニークなリストを表示することができません.lengthを指定しても適切な行が返されます。

ご協力いただければ幸いです。

CODE

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 

SAMPLE .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 
+0

おそらく 'Array [] 'の代わりに' [] 'を意味します。 – tadman

+0

それは本当です!しかし、もし私が間違っているならば、ここで私を修正してください。違いがないという違いはありませんか? –

+1

違いは 'Array []'を使用しているのは単なる奇妙なことです。最も単純な表現を使用するのが一般的に最適です。 – tadman

答えて

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" 

最後の要素ではなく、最初に一致する要素を保持するには、値を割り当てる前にキー存在チェックを行うことができます。これには、同様に行うことができます。これらのメソッドは、最初よりもはるかに良好に動作しますキーのレコードを見つけ維持すること

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 

注:また、このようにはるかに効率的に書き込むことができます

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 

キーの最後に見つかったレコードを保持するバージョンです。これは、主にハッシュ値を生成する作業回避のためです。このコードでは、slicezipで行われます。

+0

誰かがこれを逆にする方法を知っているので、ハッシュは最後に遭遇したものの代わりに最初の重複したエントリを取るだけですか? –

+1

ハッシュは、インデックスとして一意のキーを使用します。 'element [row.fields [0]]'を使うと、そのキーのハッシュの前の値が上書きされます。これにより、最後のid値が保持されている状態で正常であれば、一意性が得られます。新しいコードは世代が元のものよりも優れているので、その解決に来てくれて賞賛します! :D –

+0

ありがとう! ハッシュに最初に入力した値を保持して、次の値を無視したい場合はどうすればよいですか? –

関連する問題