逐行连接两个多行字符串

时间:2016-06-12 21:54:45

标签: ruby string concatenation

我有两个多行字符串(代表ASCII charts)。我想将它们连接起来,以便它们是并排的。

例如:

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

如上所述,我希望它们是底部对齐的。我试过这个:

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

但它有三个问题:

  • 两个街区顶部对齐。
  • 块之间没有间距。
  • 短线改变了内容:
#=> aaaabbb
#=> abbbb
#=> aaaa

我如何“阻止连接”它们?

3 个答案:

答案 0 :(得分:1)

这是一个强大的多行连接器,支持:

  • 用于加入两个块的任意字符串
  • 顶部,底部和中间对齐
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

行动中:

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 :(得分:1)

我可以发誓这个问题在几个星期前被问到并在这里得到了解答但是找不到它。

您可以使用Ruby的printf样式格式:

#!/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)

输出:

aaaa  bbb
a     bbbb
aaaa

答案 2 :(得分:1)

我实施了#34; top"和"底部"虽然我不希望添加它会很困难,但不是#34;中间",

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

由phrogs执行的测试("中"除外)。

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