2012-03-07 12 views
5

Chcę wyprowadzić tablicę skrótów o numerze name, który jest unikalny dla wszystkich skrótów. Jak mam to zrobić za pomocą ruby?Usuń duplikat z tablicy w rubinie

To mój wkład:

input = [{:name => "Kutty", :score => 2, :some_key => 'value', ...}, 
     {:name => "Kutty", :score => 4, :some_key => 'value', ...}, 
     {:name => "Baba", :score => 5, :some_key => 'value', ...}] 

Chcę wyjście wyglądać następująco:

output = [{:name => "Kutty", :score => 4, :some_key => 'value', ...}, 
      {:name => "Baba", :score => 5, :some_key => 'value', ...}] 
+0

I w zasadzie nie chce duplikat wpisu hash w tablicy !. I chcę, żeby to było więcej punktów. – Jak

+0

Jeśli dobrze rozumiem Twój komentarz, podane dane wyjściowe są błędne. Najwyższy wynik Kutty to 4. –

+0

yes mark. W każdym razie mam rozwiązanie. Tylko operator warunkowy musi się zmienić. Dzięki za znalezienie .. Zaktualizuję moje pytania. – Jak

Odpowiedz

15

po prostu usunąć duplikaty na podstawie: nazwy, po prostu spróbować;

output = input.uniq { |x| x[:name] } 

Demo here.

Edit: Ponieważ dodał sortowania wymaganie w komentarzach, oto jak wybrać wpis z najwyższym wynikiem dla każdej nazwy, jeśli używasz Rails, widzę, że już dostał odpowiedź na „standardowym” Ruby powyżej;

output = input.group_by { |x| x[:name] } 
       .map {|x,y|y.max_by {|x|x[:score]}} 

Małe wyjaśnienie może być w porządku; pierwszej linii groups wpisy po nazwie, aby każda nazwa otrzymała własną tablicę wpisów. Druga linia przechodzi przez grupy, imię i nazwisko oraz maps każda grupa nazw do pozycji z najwyższym wynikiem.

Demo here.

3
input = [{:name => "Kutty", :score => 2, :some_key => 'value'},{:name => "Kutty", :score => 4, :some_key => 'value'},{:name => "Baba", :score => 5, :some_key => 'value'}] 
p input.uniq { |e| e[:name] } 

Powyższe rozwiązanie działa dla ruby> 1.9, dla starszych wersji Ruby można użyć coś wzdłuż tych linii:

input = [{:name => "Kutty", :score => 2, :some_key => 'value'},{:name => "Kutty", :score => 4, :some_key => 'value'},{:name => "Baba", :score => 5, :some_key => 'value'}] 
unames = [] 
new_input = input.delete_if { |e| 
    if unames.include?(e[:name]) 
    true 
    else 
    unames << e[:name] 
    false 
    end 
} 
p new_input 
+0

To nie działa .. Otrzymuję ten sam wynik .. Używam ruby ​​1.8.7. W każdy sposób mi to pomaga. – Jak

1
input.uniq{|hash| hash[:name]} 
3

Spróbuj tego rozwiązania ..

input = [{:name => "Kutty", :score => 2, :some_key => 'value'}, 
     {:name => "Kutty", :score => 4, :some_key => 'value'}, 
     {:name => "Baba", :score => 5, :some_key => 'value'}] 


a = [] 
output = [] 
input.collect do |i| 
    input.delete(i) if !a.include?(i[:name]) 
    output << i if !a.include?(i[:name]) 
    a << i[:name] if !a.include?(i[:name]) 
end 


output = [{:some_key=>"value", :name=>"Kutty", :score=>2}, 
      {:some_key=>"value", :name=>"Baba", :score=>5}] 

ZAKTUALIZOWANY

Wyjście
output = {} 
input.each do |e| 
    ref = output[e[:name]] 
    if ref && ref[:score] > e[:score] 
    #nothing 
    else 
    output[e[:name]] = e 
    end 
end 

check:

puts output.values 
+0

Dzięki Sangeeth .. Twoje rozwiązanie działa dobrze, ale czekam na więcej odpowiedzi. ponieważ potrzebuję lepszego podejścia. – Jak

+0

Dzięki Arun .. Zaktualizowałem odpowiedź, proszę sprawdzić. – sangeethkumar

+0

To znacznie lepsze podejście. dzięki – Jak