114 Stimmen

Gibt es in Ruby eine Array-Methode, die 'select' und 'map' kombiniert?

Ich habe ein Ruby-Array, das einige String-Werte enthält. Das muss ich tun:

  1. Alle Elemente finden, die einem Prädikat entsprechen
  2. Durchlaufen Sie die übereinstimmenden Elemente durch eine Transformation
  3. Rückgabe der Ergebnisse als Array

Im Moment sieht meine Lösung wie folgt aus:

def example
  matchingLines = @lines.select{ |line| ... }
  results = matchingLines.map{ |line| ... }
  return results.uniq.sort
end

Gibt es eine Array- oder Enumerable-Methode, die Select und Map in einer einzigen logischen Anweisung kombiniert?

1voto

Weston Ganger Punkte 5612

Versuchen Sie es doch mal mit meiner Bibliothek Rearmed Ruby in dem ich die Methode Enumerable#select_map . Hier ein Beispiel:

items = [{version: "1.1"}, {version: nil}, {version: false}]

items.select_map{|x| x[:version]} #=> [{version: "1.1"}]
# or without enumerable monkey patch
Rearmed.select_map(items){|x| x[:version]}

1voto

Bibek Shrestha Punkte 29551

Wenn Sie nicht zwei verschiedene Arrays erstellen wollen, können Sie compact! aber seien Sie vorsichtig damit.

array = [1,1,1,2,3,4]
new_array = map{|n| n*3 if n==1}
new_array.compact!

Interessanterweise, compact! entfernt an Ort und Stelle die Zahl Null. Der Rückgabewert von compact! ist das gleiche Array, wenn es Änderungen gab, aber null, wenn es keine Änderungen gab.

array = [1,1,1,2,3,4]
new_array = map{|n| n*3 if n==1}.tap { |array| array.compact! }

Das wäre ein Einzeiler.

0voto

Ihre Version:

def example
  matchingLines = @lines.select{ |line| ... }
  results = matchingLines.map{ |line| ... }
  return results.uniq.sort
end

Meine Version:

def example
  results = {}
  @lines.each{ |line| results[line] = true if ... }
  return results.keys.sort
end

Dies wird 1 Iteration (außer der Sortierung), und hat den zusätzlichen Bonus der Beibehaltung Einzigartigkeit (wenn Sie nicht über uniq kümmern, dann machen Sie einfach Ergebnisse ein Array und results.push(line) if ...

-1voto

zw963 Punkte 1107

Hier ist ein Beispiel. Es entspricht nicht Ihrem Problem, aber es kann das sein, was Sie wollen, oder es kann einen Hinweis auf Ihre Lösung geben:

def example
  lines.each do |x|
    new_value = do_transform(x)
    if new_value == some_thing
      return new_value    # here jump out example method directly.
    else
      next                # continue next iterate.
    end
  end
end

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X