2016-06-12 11 views
1

Ich habe zwei mehrzeilige Zeichenfolgen (entspricht ASCII charts). Ich möchte sie verketten, so dass sie Seite an Seite stehen.Verketten Sie zwei mehrzeilige Zeichenfolgen Zeile für Zeile

Zum Beispiel:

s1 = "aaaa 
a 
aaaa" 
s2 = "bbb 
bbbb" 
puts s1.multi_concat(s2) 
#=> aaaa 
#=> a bbb 
#=> aaaa bbbb 

Wie oben zu sehen ist, würde Ich mag sie unten ausgerichtet sein. Ich habe versucht, dieses:

class String 
    def multi_concat(s2) 
    lines.map(&:chomp).zip(s2.lines.map(&:chomp)).map(&:join).join("\n") 
    end 
end 

Aber es hat drei Probleme:

  • Die beiden Blöcke sind top-ausgerichtet sind.
  • Zwischen den Blöcken ist kein Abstand vorhanden.
  • Kurz Linien verschieben, um den Inhalt:
#=> aaaabbb 
#=> abbbb 
#=> aaaa 

Wie kann ich "Block verketten" sie?

Antwort

1

Hier ist eine robuste Verkettungs mehrzeiligen, die unterstützt:

  • Arbitrary-Strings zu verbinden, um zwei Blöcke
  • oben, unten, und mittlere Ausrichtung
class String 
    def multi_concat(str2,options={}) 
    options[:pad] ||= '' 
    options[:align] ||= :top 

    chomped1, chomped2 = [self,str2].map{ |s| s.lines.map(&:chomp) } 
    template = "%-#{chomped1.map(&:length).max}s#{options[:pad]}%s" 
    delta = chomped2.length - chomped1.length 
    unless delta==0 
     shorter = delta>0 ? chomped1 : chomped2 
     delta = delta.abs 
     padding = ['']*delta 
     case options[:align] 
     when :top then shorter.concat(padding) 
     when :bottom then shorter.unshift(*padding) 
     when :middle 
     s1,s2 = *padding.each_cons((delta/2.0).ceil) 
     shorter.unshift(*s2) 
     shorter.concat(s1) 
     end 
    end 
    chomped1.zip(chomped2).map{ |a| template % a }.join("\n") 
    end 
end 

In Aktion:

a = "aaa\naaaa" 
b = "bbbb\n\n\nbb" 
puts a.multi_concat(b) 
#=> aaa bbbb 
#=> aaaa 
#=>  
#=>  bb 

puts a.multi_concat(b, pad:' -> ') 
#=> aaa -> bbbb 
#=> aaaa -> 
#=>  -> 
#=>  -> bb 

puts a.multi_concat(b, pad:' ', align: :bottom) 
#=>  bbbb 
#=>  
#=> aaa 
#=> aaaa bb 

puts a.multi_concat(b, pad:' ', align: :middle) 
#=>  bbbb 
#=> aaa 
#=> aaaa 
#=>  bb 

puts b.multi_concat(a, pad:' ') 
#=> bbbb aaa 
#=>  aaaa 
#=>  
#=> bb 
1

Ich könnte schwören, dass diese Frage vor ein paar Wochen hier gestellt und beantwortet wurde, aber nicht gefunden werden kann.

Sie können mit Rubys printf-Formatierung:

#!/usr/bin/env ruby 

def format(s1, s2) 
    lines1 = s1.split("\n") 
    lines2 = s2.split("\n") 
    max_s1 = lines1.map { |s| s.length }.max 
    format_string = "%-#{max_s1 + 2}s%s" 
    lines1.zip(lines2).each do |s1, s2| 
    puts format_string % [s1, s2] 
    end 
end 


s1 = "aaaa 
a 
aaaa" 

s2 = "bbb 
bbbb" 

format(s1, s2) 

Ausgänge:

aaaa bbb 
a  bbbb 
aaaa 
+0

Schön. Ich mag die Verwendung des Sprintf für das Padding ('+ 2'), aber beachte, dass diese Antwort die Anforderung der unteren Ausrichtung nicht löst. – Phrogz

1

I umgesetzt "oben" und "unten" ausrichten, aber nicht "Mitte", obwohl ich don‘ Ich erwarte, dass es schwierig wäre, das hinzuzufügen.

def multi_concat_top(s1,s2,sep=' ') 
    multi_concat(s1.split("\n"), s2.split("\n"), sep).join("\n") 
end 

def multi_concat_bottom(s1,s2,sep=' ') 
    multi_concat(s1.split("\n").reverse, s2.split("\n").reverse, sep). 
    reverse.join("\n") 
end 

def multi_concat(a1,a2,sep) 
    mx1 = a1.max_by(&:size).size 
    [a1.size, a2.size].max.times.map { |i| 
    "%s%s%s" % [a1.fetch(i,'').ljust(mx1), sep, a2.fetch(i,'')] } 
end 

s1 = "aaaa\na\naaaa" 
s2 = "bbb\nbbbb" 

puts s1 
# aaaa 
# a 
# aaaa 

puts s2 
# bbb 
# bbbb 

puts multi_concat_top(s1,s2,' -> ') 
# aaaa -> bbb 
# a -> bbbb 
# aaaa -> 

puts multi_concat_bottom(s1,s2,' -> ') 
# aaaa -> 
# a -> bbb 
# aaaa -> bbbb 

Tests von phrogs (mit Ausnahme von "Mitte") durchgeführt folgen.

s1 = "aaa\naaaa" 
s2 = "bbbb\n\n\nbb" 

puts s1 
# aaa 
# aaaa 
puts s2 
# bbbb 
# 
# 
# bb 

puts a.multi_concat_top(s1,s2) 
# aaa bbbb 
# aaaa 
#  
#  bb 

puts a.multi_concat_top(s1,s2,' -> ') 
# aaa -> bbbb 
# aaaa -> 
#  -> 
#  -> bb 

puts a.multi_concat_bottom(s1,s2) 
#  bbbb 
#  
# aaa 
# aaaa bb 

puts multi_concat_top(b,a) 
# bbbb aaa 
#  aaaa 
#  
# bb 
+1

Schöner Trick mit der '.reverse'! Erinnert mich an etwas, was JEGII einmal geschrieben hat: _ ["... es erinnert mich an eine meiner Lieblingsregeln der Computertechnik: Wenn du hoffnungslos feststeckst, reverse die Daten. Ich kann mich nicht erinnern, wer mich diese Regel lehrte und ich habe keine irdische Idee, warum es funktioniert, aber es hilft sicher sehr. "] (http://rubyquiz.com/quiz113.html) _ – Phrogz

Verwandte Themen