如何明智地在对象周围分割数组

时间:2014-02-17 15:34:48

标签: ruby arrays

我有一个不确定长度的数组,让我们说[1,2,3,4,5]。我想从1之前的所有内容中减去3,并将1添加到3之后的所有内容中,制作示例[0,1,3,5,6]。如果没有3,请向所有内容添加1[1,2,4,5] => [2,3,5,6]。这样做最优雅的方式是什么?

7 个答案:

答案 0 :(得分:6)

a = [1, 2, 3, 4, 5]
n = a.index(3) || -1
a.map.with_index{|e, i| e + (i <=> n)}
# => [0, 1, 3, 5, 6]

答案 1 :(得分:1)

因此,为了在上严格地通过数组传递,你需要从最后开始,向每个元素添加一个,直到你达到3,然后开始减去一个。

arr.reverse_each.slice_before(3).flat_map.with_index do |ar,i|
  ar.map do |x|  
    x += 1 if i == 0 unless x == 3    
    x -= 1 if i == 1    
    x
  end  
end.reverse

你可以更简洁地编写内部块,但我喜欢它显式,因为这段代码很难按原样阅读。

我认为这不会在可读性或性能方面给你带来任何好处,但它肯定是功能! (说真的,用@ sawa的答案,很漂亮)

答案 2 :(得分:0)

尝试类似(假设数组已排序)

a = [1,2,3,4,5]
n = 3
a.include?(n) ? a.map {|e| e < n ? e-1 : e > n ? e + 1 : e } : a.map {|e| e + 1} 
# => [0, 1, 3, 5, 6]

如果您喜欢这种方式,那就是单行的sintax ......

if a.include?(n)  
   a.map {|e| e < n ? e - 1 : e > n ? e + 1 : e }
else
   a.map {|e| e + 1}
end

答案 3 :(得分:0)

if your_array.include?(3)    
  your_array.map do |item|
    if item > 3
      item + 1
    elsif item < 3
      item -1
    else
      item
    end
  end
else
  your_array.map{ |item| item + 1 }
end

答案 4 :(得分:0)

def doit(a)
  n = a.include?(3) ? -1 : 1
  a.map { |i| (i==3 && n == -1) ? (n = 1; i) : i + n }
end

doit([1,2,3,4,5]) #=> [0, 1, 3, 5, 6] 
doit([6,5,4,2,1]) #=> [7, 6, 5, 3, 2]
doit([1,2,3,4,3]) #=> [0, 1, 3, 5, 4] 

我在第一个之后每三个添加一个,但如果它们保持不变,这是一个简单的修复。

答案 5 :(得分:0)

我做如下:

def add_sub(a)
  ind = a.index(3)|| -1
  a.each_index.map do |i|
    if ind < i
      a[i] + 1
    elsif ind > i
      a[i] - 1
    else
      a[i]
    end
  end
end

a1 = [1, 2, 3, 4, 5]
a2 = [1, 2, 7, 4, 5]

add_sub(a1) # => [0, 1, 3, 5, 6]
add_sub(a2) # => [2, 3, 8, 5, 6]

答案 6 :(得分:0)

使用@sawa的回答

如果您想手动浏览阵列,可以采用以下方式:

def trans_around(arr, elmt)
  ret = []

  found_at = -1 

  for i in 0...(arr.length) 
    if arr[i] == elmt
      found_at = i 
      break
    else
      ret << (arr[i] - 1)
    end
  end

  if (found_at > -1)
    ret << arr[found_at]

    for i in (found_at + 1)...(arr.length)
      ret << (arr[i] + 1)
    end
  else
    # rectify all the -1's we've done
    ret.each_with_index { |e,i| ret[i] += 2 }
  end

  return ret
end