2016-05-17 8 views
3

Ich habe ein Array wie folgtRubin inneren Flatten (Array von Arrays)

[ 
    [[0, :a], [2, :b]], 
    [3, :c], 
    [4, :d], 
    [[5, :e], [6, :f], [7, :g]] 
] 

Das heißt, ein Array von Elementen, die entweder (1) 2-Element-Arrays, oder (2) ein Array von 2-Element-Arrays.

Ich versuche eine elegante Möglichkeit zu finden, dieses Array so zu "glätten", dass Elemente (2) in Elemente auf Root-Ebene expandiert werden. In diesem Beispiel:

[[0, :a], [2, :b], [3, :c], [4, :d], [5, :e], [6, :f], [7, :g]] 

Das ist fast wie Array#flatten(depth), mit der Ausnahme depth Bedürfnisse von innen heraus zu arbeiten, anstatt außen in

Die tatsächlichen Arrays sehr groß werden können, so dass ich dies nicht tun. möchte aus Leistungsgründen Elemente in ein neues Array in einer Schleife schieben (<<). Aus irgendeinem Grund kann ich nicht daran denken, wie man eine Kombination von map, flatten, flat_map oder andere effizientere Enumerable Methoden verwenden kann, um dies zu erreichen, ohne eine C++ - Art Vorbelegung-und-füllen-Schleife zu schreiben. Kann jemand an einen mehr ryxistischen Weg denken, dies zu tun?

Antwort

7

Eine Möglichkeit ist zu tun:

array.flatten.each_slice(2).to_a 
1

Posting eine andere Lösung hier für die Nachwelt:

array.flat_map{|el| el.first.is_a?(Array) ? el : [el]} 

Diese Lösung Griffe auch, wenn die innerste Arrays variabler Länge sind - das heißt, die Gesamt Array ist ein Array von (1) n-Element-Arrays oder (2) Arrays von n-Element-Arrays, wobei n für ein gegebenes Element nicht unbedingt gleich ist. Zum Beispiel

[ 
    [1,2,3], 
    [[4,5], [6,7,8,9]] 
]