如何在一个循环中修改数组的内容

时间:2017-07-26 22:27:12

标签: ruby

我有一个如下所示的数组:

strings= ['','','','   Some text', '', '     Some another text']

如何仅映射条纹文本? 现在我这样做:

strings.select!{|string| !string.emtpy?}
strings.map!{|string| string.strip}

你可以看到有2个循环。我觉得效率不高

5 个答案:

答案 0 :(得分:1)

您只需添加lazy即可为每个步骤创建一个中间数组。 它仍然是2次迭代,但内存效率高,但可读性

strings.lazy.select {|string| !string.empty? }.map {|string| string.strip }.to_a

答案 1 :(得分:1)

您可以在此处使用grep

strings.grep(/.+/, &:strip)
 #=> ["Some text", "Some another text"]

答案 2 :(得分:1)

 `strings.map {|string| string.strip if string.strip.size > 0}`.compact

> ["Some text", "Some another text"]

说明:

strings.map {|string| string.strip if string.strip.size > 0}

它将返回:

> [nil, nil, nil, "Some text", nil, "Some another text"]

如果string为空,则为nil。否则它将返回剥离的文本。

.compact:返回self的副本,删除所有nil元素。

所以,[nil, nil, nil, "Some text", nil, "Some another text"].compact 将是:> ["Some text", "Some another text"]

答案 3 :(得分:0)

您也可以通过一个循环使用#injectSO linkRuby doc link)来实现这一目标:

strings.inject([]) { |arr, val| val.present? ? arr.push(val.strip) : arr }

答案 4 :(得分:0)

这不是大多数内存效率(因为你创建了另一个数组)购买将在一个循环中完成工作(可能有更短的方法来编写此代码。我也使用text!=''代替emtpy?因为我不使用Rails

strings = ['','','','   Some text', '', '     Some another text']
stripped_strings = []
strings.each do |text|
if !(text=='')
   stripped_strings << text.strip
end
puts stripped_strings

输出将是[&#39;某些文字&#39;,&#39;其他文字&#39;]

下一个方法适用于Ruby 2.1.7我不确定它是否适用于其他版本。我认为这有点风险。但是你不需要额外的数组

strings = ['','','','   Some text', '', '     Some another text']
strings.select! do |text|
    text.strip!
    text != ''
end

这是有效的,因为Ruby将String视为对象。告诉我评论如果您想要更多解释

第三个选项也有一点风险就是在迭代时从数组中删除元素。为此,我没有使用string.each,因为在运行每个项目时从数组中删除项目也可能会有问题。现在我不需要担心每个人是否克隆|text|(然后条带!不会像前面的例子那样改变原始数组)

strings = ['','','','   Some text', '', '     Some another text']
$i = strings.length - 1
while $i >= 0 do
  if strings[$i] == ''
    strings.delete_at($i)
  else
    strings[$i].strip!
  end
  $i -= 1
end
puts strings