在Ruby中将数组元素移动到另一个数组

3

一个简单的 Ruby 问题。假设我有一个包含 10 个字符串的数组,我想将 array[3] 和 array[5] 的元素移动到一个全新的数组中。新数组将只有我从第一个数组中移动的这两个元素,而第一个数组则只剩下 8 个元素,因为其中两个已经被移走了。

5个回答

4

使用Array#slice!从第一个数组中删除元素,并使用Array#<<将它们追加到第二个数组中:

arr1 = ['Foo', 'Bar', 'Baz', 'Qux']
arr2 = []

arr2 << arr1.slice!(1)
arr2 << arr1.slice!(2)

puts arr1.inspect
puts arr2.inspect

输出:

["Foo", "Baz"]
["Bar", "Qux"]

根据您的具体情况,您可能会发现数组上的其他方法更加有用,例如Enumerable#partition

arr = ['Foo', 'Bar', 'Baz', 'Qux']
starts_with_b, does_not_start_with_b = arr.partition{|word| word[0] == 'B'}

puts starts_with_b.inspect
puts does_not_start_with_b.inspect

输出:

["Bar", "Baz"]
["Foo", "Qux"]

2
a = (0..9).map { |i| "el##{i}" }
x = [3, 5].sort_by { |i| -i }.map { |i| a.delete_at(i) }
puts x.inspect
# => ["el#5", "el#3"]
puts a.inspect
# => ["el#0", "el#1", "el#2", "el#4", "el#6", "el#7", "el#8", "el#9"]

如评论所述,有一些技巧可以使索引保持在原地。 可以通过首先使用a.values_at(*indices)获取所有所需元素,然后像上面那样删除它们来避免这种情况。


你为什么使用了 #sort_by - Arup Rakshit
1
如果我不按降序删除它们,索引就会混乱。如果我删除#3,则#5会下降到位置#4;如果我然后删除#5,则我已经删除了“el#6”而不是“el#5”。但是,如果我从最大的索引开始向下删除它们,则较小的索引将保持原位。 - Amadan
进一步说,sort 不仅限于其元素响应 - 的数组。 - Cary Swoveland
@CarySwoveland:不是,但delete_at是。数组必须包含整数,否则代码会在后面失败。我确实同意.sort.reverse更易读。 - Amadan

2

代码:

arr = ["null","one","two","three","four","five","six","seven","eight","nine"]

p "Array: #{arr}"

third_el = arr.delete_at(3)
fifth_el = arr.delete_at(4)
first_arr = arr
p "First array: #{first_arr}"

concat_el = third_el + "," + fifth_el
second_arr = concat_el.split(",")
p "Second array: #{second_arr}"

输出:

c:\temp>C:\case.rb
"Array: [\"null\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"s
even\", \"eight\", \"nine\"]"
"First array: [\"null\", \"one\", \"two\", \"four\", \"six\", \"seven\", \"eight
\", \"nine\"]"
"Second array: [\"three\", \"five\"]"

0
这是一个方式:
vals  = arr.values_at *pulls
arr   = arr.values_at *([*(0...arr.size)] - pulls)

试一下。

arr   = %w[Now is the time for all Rubyists to code]
pulls = [3,5]

vals  = arr.values_at *pulls
  #=>     ["time", "all"]
arr   = arr.values_at *([*(0...arr.size)] - pulls)
  #=>     ["Now", "is", "the", "for", "Rubyists", "to", "code"]

arr   = %w[Now is the time for all Rubyists to code]
pulls = [5,3]

vals  = arr.values_at *pulls
  #=>     ["all", "time"]
arr   = arr.values_at *([*(0...arr.size)] - pulls)
  #=>     ["Now", "is", "the", "for", "Rubyists", "to", "code"]

0
为什么不从最高索引开始删除呢?
arr = ['Foo', 'Bar', 'Baz', 'Qux']
index_array = [2, 1]
new_ary = index_array.map { |index| arr.delete_at(index) }
new_ary # => ["Baz", "Bar"]
arr # => ["Foo", "Qux"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接