拆分字符串以获取Ruby的所有子字符串的最佳方法是什么?

Jim*_*ang 9 ruby string

例如,单词"stack",我想得到一个类似的数组:

['s', 'st', 'sta', ... 'stack', 't', 'ta', ... , 'c', 'ck', 'k']
Run Code Online (Sandbox Code Playgroud)

我是通过这样的代码做到的:

def split_word(str)
  result = []
  chas = str.split("")
  len = chas.size
  (0..len-1).each do |i|
    (i..len-1).each do |j|
      result.push(chas[i..j].join)
    end
  end
  result.uniq
end
Run Code Online (Sandbox Code Playgroud)

那有更好,更干净的方法吗?谢谢.

Mla*_*vić 11

def split_word s
  (0..s.length).inject([]){|ai,i|
    (1..s.length - i).inject(ai){|aj,j|
      aj << s[i,j]
    }
  }.uniq
end
Run Code Online (Sandbox Code Playgroud)

您也可以考虑使用Set而不是Array来获得结果.

PS:这是基于阵列产品的另一个想法:

def split_word s
  indices = (0...s.length).to_a
  indices.product(indices).reject{|i,j| i > j}.map{|i,j| s[i..j]}.uniq
end
Run Code Online (Sandbox Code Playgroud)


小智 7

def substrings(str)
  output = []
  (0...str.length).each do |i|
    (i...str.length).each do |j|
      output << str[i..j]
    end
  end
  output
end
Run Code Online (Sandbox Code Playgroud)

这只是你的方法的清理版本,它的工作步骤更少=)


tok*_*and 5

我写道:

def split_word(s)
  0.upto(s.length - 1).flat_map do |start| 
    1.upto(s.length - start).map do |length| 
      s[start, length]
    end
  end.uniq
end

groups = split_word("stack")
# ["s", "st", "sta", "stac", "stack", "t", "ta", "tac", "tack", "a", "ac", "ack", "c", "ck", "k"]
Run Code Online (Sandbox Code Playgroud)

使用map(功能)通常更清晰,更紧凑,而不是模式init empty + each + append + return(imperative).