Каков наилучший способ конвертировать массив в хеш в Ruby

Типичные операционные системы не предоставляют возможности вставки или удаления содержимого файла «на месте». Вам нужно будет написать функцию, которая считывает первый файл и создает файл new , содержащий строки, которые вы хотите сохранить. Затем, когда вы закончите, удалите старый файл и переименуйте новый в старое имя.

В псевдокоде:

open original file IN for reading
create new output file OUT
read the first two lines from IN
write these lines to OUT
for each line to skip:
    read a line from IN
for the remainder of the file:
    read a line from IN
    write the line to OUT
close IN
close OUT
delete IN
rename OUT to IN

Преимущество этого метода над некоторыми из другие представлены в том, что он не требует, чтобы вы сначала прочитали весь файл в памяти. Вы не указали, насколько велика ваша максимальная предел размера, но если это что-то вроде 100 МБ, вы можете обнаружить, что загрузка файла в память не является приемлемым использованием пространства.

118
задан Max 30 September 2014 в 14:42
поделиться

5 ответов

Если числовые значения являются индексами seq, то у нас могли быть более простые пути... Вот мое представление кода, Мой Ruby немного ржав

   input = ["cat", 1, "dog", 2, "wombat", 3]
   hash = Hash.new
   input.each_with_index {|item, index|
     if (index%2 == 0) hash[item] = input[index+1]
   }
   hash   #=> {"cat"=>1, "wombat"=>3, "dog"=>2}
-1
ответ дан Gishu 1 October 2014 в 01:42
поделиться

Просто используйте Hash[*array_variable.flatten]

, Например:

a1 = ['apple', 1, 'banana', 2]
h1 = Hash[*a1.flatten(1)]
puts "h1: #{h1.inspect}"

a2 = [['apple', 1], ['banana', 2]]
h2 = Hash[*a2.flatten(1)]
puts "h2: #{h2.inspect}"

Используя Array#flatten(1) пределы рекурсия так Array ключи и значения работают как ожидалось.

144
ответ дан Eric Platon 1 October 2014 в 01:42
поделиться

Не уверенный, если это - лучший способ, но это работает:

a = ["apple", 1, "banana", 2]
m1 = {}
for x in (a.length / 2).times
  m1[a[x*2]] = a[x*2 + 1]
end

b = [["apple", 1], ["banana", 2]]
m2 = {}
for x,y in b
  m2[x] = y
end
0
ответ дан lindes 1 October 2014 в 01:42
поделиться

Редактирование: Видел ответы, отправленные, в то время как я писал, Хеш [a.flatten] кажется способом пойти. Должно быть, пропустил тот бит в документации, когда я продумывал ответ. Мысль решения, которые я записал, может использоваться в качестве альтернатив при необходимости.

вторая форма более проста:

a = [[:apple, 1], [:banana, 2]]
h = a.inject({}) { |r, i| r[i.first] = i.last; r }

= массив, h = хеш, r = хеш возвращаемого значения (тот мы накапливаемся в), я = объект в массиве

самый опрятный способ, которым я могу думать о выполнении первой формы, является чем-то вроде этого:

a = [:apple, 1, :banana, 2]
h = {}
a.each_slice(2) { |i| h[i.first] = i.last }
9
ответ дан Daemin 1 October 2014 в 01:42
поделиться

Добавление к ответу, но с использованием анонимных массивов и аннотирования:

Hash[*("a,b,c,d".split(',').zip([1,2,3,4]).flatten)]

Разбирая этот ответ, начиная с внутренней стороны:

  • «a, b, c, d» на самом деле является строкой.
  • разделить запятыми в массив.
  • zip , который вместе со следующим массивом.
  • [1,2,3,4] - это фактический массив.

Промежуточный результат:

[[a,1],[b,2],[c,3],[d,4]]

flatten затем преобразует это в:

["a",1,"b",2,"c",3,"d",4]

, а затем:

* [«a», 1, «b», 2, «c», 3, «d», 4] разворачивает это в «a», 1, «b», 2, «c», 3, «d», 4

, которые мы можем использовать в качестве аргументов метода Hash [] :

Hash[*("a,b,c,d".split(',').zip([1,2,3,4]).flatten)]

, что дает:

{"a"=>1, "b"=>2, "c"=>3, "d"=>4}
3
ответ дан 24 November 2019 в 01:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: