2017-06-05 9 views
0

Ich habe 2 Strings:Wie 2 Strings abwechselnd in Schienen zusammenführen?

a = "qwer" 

b = "asd" 

Result = "qawsedr" 

Same die Länge b ist größer als ein. zeige abwechselnd die Charaktere an.

Was ist der beste Weg, dies zu tun? Soll ich Schleife verwenden?

+0

Sie die Antwort von max und dann verwenden könnte concat der Rest der Zeichenfolge links –

+0

Was meinen Sie? –

Antwort

2

Sie können die Zeichen aus dem a und b Zeichenfolge mit ihnen als Arrays zu arbeiten und sie zip mit „merge“, dann, dann join sie.

Im Falle von Strings mit unterschiedlicher Länge, müssen die Array-Werte umgekehrt werden, so:

def merge_alternately(a, b) 
    a = a.chars 
    b = b.chars 
    if a.length >= b.length 
    a.zip(b) 
    else 
    array = b.zip(a) 
    array.map{|e| e != array[-1] ? e.reverse : e} 
    end 
end 

p merge_alternately('abc', 'def').join 
# => "adbecf" 
p merge_alternately('ab', 'zsd').join 
# => "azbsd" 
p merge_alternately('qwer', 'asd').join 
# => "qawsedr" 
+0

Hmmm, versuche 'a =" ab "' 'b =" zsd "' es gibt 'azbs'. es muss 'azbsd' geben –

+0

Das liegt an der Länge der Werte im Array, aber Sie können es überprüfen, bevor Sie den' zip' Schritt ausführen. –

+0

Ich habe die Antwort aktualisiert und die Array-Werte umgekehrt, wenn die Länge von a kleiner als b ist. –

0

Sebastián Antwort bekommt den Job zu erledigen, aber es ist unnötig komplex. Hier ist eine Alternative:

def merge_alternately(a, b) 
    len = [a.size, b.size].max 
    Array.new(len) {|n| [ a[n], b[n] ] }.join 
end 
merge_alternately("ab", "zsd") 
# => "azbsd" 

Die erste Zeile erhält die Größe der längeren Zeichenfolge. Die zweite Zeile verwendet die Blockform des Array-Konstruktors. es liefert die Indizes von 0 bis len-1 zum Block, was zu einem Array wie [["a", "z"], ["b", "s"], [nil, "d"]] führt. join verwandelt es in eine Zeichenkette, die bequem to_s auf jedem Gegenstand anruft, der nil in "" dreht.

Hier ist eine andere Version, die im Grunde das Gleiche tut, aber überspringt die Zwischenfelder:

def merge_alternately(a, b) 
    len = [a.size, b.size].max 
    len.times.reduce("") {|s, i| s + a[i].to_s + b[i].to_s } 
end 

len.times ein Enumerator ergibt, dass die Indizes von 0 zu len-1 ergibt. reduce beginnt mit einer leeren Zeichenfolge s und hängt in jeder Iteration die nächsten Zeichen aus a und b (oder "" - nil.to_s - wenn eine Zeichenfolge aus Zeichen besteht).

Sie können sowohl auf repl.it sehen: https://repl.it/I6c8/1

Just for fun, hier ein paar mehr Lösungen. Dieser funktioniert ähnlich wie Sebastián-Lösung, sondern füllt die erste Anordnung von Zeichen mit nil s, wenn es kürzer als den zweiten:

def merge_alternately(a, b) 
    a, b = a.chars, b.chars 
    a[b.size - 1] = nil if a.size < b.size 
    a.zip(b).join 
end 

Und es wäre keine Ruby-Antwort ohne ein wenig gsub sein:

def merge_alternately2(a, b) 
    if a.size < b.size 
    b.gsub(/./) { a[$`.size].to_s + $& } 
    else 
    a.gsub(/./) { $& + b[$`.size].to_s } 
    end 
end 

sehen Sie diese beiden auf repl.it: https://repl.it/I6c8/2

Verwandte Themen