如何制作变换Ruby数组

时间:2017-07-15 22:23:25

标签: arrays ruby hash

如何转换此数组?

test = [ 'first_array', '1', '2', '3', 'second_array', '4', '5']

需要格式。

first_array = ['1', '2', '3']
second_array = ['4' '5']

5 个答案:

答案 0 :(得分:0)

如果您只需要将阵列分成两部分,可以使用slice这样完成:

test = ['first_array', '1', '2', '3', 'second_array', '4', '5']

first_array = test.slice(1, 3)
second_array = test.slice(5, 2)

答案 1 :(得分:0)

如果您要从数组中的名称创建变量(例如first_arraysecond_array),那么您应该考虑使用哈希,因为您无法动态创建变量红宝石。

要完成此操作,您可以将chunk_whilewith_object一起使用,例如:

test.chunk_while { |_, a| a =~ /^\d+$/ }.with_object({}) { |t, h| h[t.shift] = t }
#=> {"first_array"=>["1", "2", "3"], "second_array"=>["4", "5"]}

如果您不关心名称,并希望手动将值分配给不同的变量,那么您可以使用map代替with_object并将它们直接分配给变量:

first_array, second_array = test.chunk_while { |_, a| a =~ /^\d+$/ }.map { |t| t[1..-1] }

first_array
#=> ["1", "2", "3"]

second_array
# => ["4", "5"]

请注意,它仅在最终元素为数字且仅提供两个组时才有效,否则它将返回初始数组中提供的所有组,因此您需要为每个组创建变量,或者更好,只需使用数组数组创建一个变量:

test = [ 'first_array', '1', '2', '3', 'second_array', '4', '5', 'third_array', '7', '8', '9', '10']
arrays = test.chunk_while { |_, a| a =~ /^\d+$/ }.map { |t| t[1..-1] }

arrays
#=> [["1", "2", "3"], ["4", "5"], ["7", "8", "9", "10"]]

答案 2 :(得分:0)

正如本answer中所解释的那样,由于您无法在Ruby中动态创建局部变量,因此可能只使用哈希。

test.chunk_while { |a,b| a[/\d/] && b[/\d/] }
    .each_slice(2)
    .map { |k,v| [*k, v] }
    .to_h

#=> { "first_array" => ["1", "2", "3"], "second_array" => ["4", "5"] } 

答案 3 :(得分:0)

对于Ruby版本1.9+,无法创建局部变量。另一种方法(由@ sagarpandya82建议)是创建一个哈希。可以这样做。

def split_em(arr)
  arr.each_with_object([]) { |o,a| o =~ /\d+/ ? (a.last << o) : a << o << [] }
end

a = split_em(test)
  #=> ["first_array", ["1", "2", "3"], "second_array", ["4", "5"]]
Hash[*a]
  #=> {"first_array"=>["1", "2", "3"], "second_array"=>["4", "5"]}

另一种方法是创建实例变量。

class Test
  def initialize(*arr)
    split_em(arr).each_slice(2) { |k,v| instance_variable_set("@#{k}", v) }
    end
  end
end

t = Test.new(*test)
  #=> #<Test:0x00000000bcc938 @first_array=["1", "2", "3"], @second_array=["4", "5"]>
t.instance_variables.each { |v| puts "#{v} = #{t.instance_variable_get(v)}" }
@first_array = ["1", "2", "3"]
@second_array = ["4", "5"]

答案 4 :(得分:0)

您可以使用Enumerable#slice_before

test = ['first_array', '1', '2', '3', 'second_array', '4', '5']

test.slice_before {|e| e.include?("_")}.map {|_,*arr| arr } 
#=> [["1", "2", "3"], ["4", "5"]]