Как получить следующий и предыдущий элемент в массиве Ruby - PullRequest
1 голос
/ 18 октября 2019

У меня есть этот массив, и мне нужно заменить его элементы умножением его предыдущего и следующего.

Я делаю следующее:

   array.each_with_index{|element, index|
      next_element = array[index+1]
      previous_element = array[index-1]
    }

   array.map! {|a|
      if a == array.first
        a = a * next_element
      elsif a == array.last
        a = a * previous_element
      else
        a = next_element * previous_element
      end
      }

Ожидаю следующий результат:

array = [4, 1, 6, 7, 9, 3, 0]       #given array
array = [4, 24, 7, 54, 21, 0, 0]    #array replaced

Я получаю следующую ошибку:

undefined local variable or method `next_element' for Arrays:Class

Есть ли простой способ получить предыдущий и следующий элемент данного элемента массива?

Я использую метод array.map!, верно?

Ответы [ 4 ]

3 голосов
/ 18 октября 2019

Это будет работать:

array = [4, 1, 6, 7, 9, 3, 0]

[nil, *array, nil].each_cons(3).map { |l, m, r| (l || m) * (r || m) }
#=> [4, 24, 7, 54, 21, 0, 0]

Массив окружен значениями nil, поэтому у каждого элемента есть соседи. each_cons(3) затем возвращает каждый элемент вместе с его соседями в map, что умножает левого (l) на правого (r) соседа, возвращаясь к среднему элементу (m), если один из соседейбывает nil.

1 голос
/ 18 октября 2019

Вы можете сделать следующее,

[array[0..1].inject(:*)] + array[0..-2].map.with_index { |x,i| x * (array[i+2] || array[i+1]) }
# => [4, 24, 7, 54, 21, 0, 0]
0 голосов
/ 18 октября 2019

Похоже, что each_cons было бы хорошо здесь:

[array.first] + array.each_cons(3).map { |p, _, n| p * n } + [array.last]
#=> [4, 24, 7, 54, 21, 0, 0]

Это требует дополнительной работы (например, если массив пуст, это вернет [nil, nil]), ноЯ уверен, что вы можете выяснить эти крайние случаи.

0 голосов
/ 18 октября 2019

Вы определили next_element и previous_element внутри цикла, поэтому они становятся неопределенными в конце. Это простой обход вашего кода, я предполагаю, что вы хотите оставить первый и последний элемент без изменений. Вам не нужно использовать map

array.each_with_index do |element, index|   
  if element != array.first && element != array.last
    array[index] = array[index+1] * array[index-1]      
  end 
end 

array => [4, 24, 168, 1512, 4536, 0, 0]

Это не то, что вы ожидали, почему? Поскольку ваш элемент array[index] будет меняться после каждой итерации, вы можете печатать массив после каждой итерации, чтобы увидеть результат

. Я бы предложил вам использовать другой массив для сохранения значения массива, например

b =[]
array.each_with_index do |element, index|
  b[index] = array[index]
    if element != array.first && element != array.last
  b[index] = array[index+1] * array[index-1]
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...