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
Sie die Antwort von max und dann verwenden könnte concat der Rest der Zeichenfolge links –
Was meinen Sie? –