Как вернуть часть массива в Ruby?

Со списком в Python я могу вернуть его часть, используя следующий код:

foo = [1,2,3,4,5,6]
bar = [10,20,30,40,50,60]
half = len(foo) / 2
foobar = foo[:half] + bar[half:]

Поскольку Ruby все делает в массивах, мне интересно, есть ли что-то подобное.


person Christian Stade-Schuldt    schedule 29.03.2009    source источник


Ответы (5)


Да, Ruby имеет синтаксис разделения массива, очень похожий на Python. Вот ri документация по методу индексации массива:

--------------------------------------------------------------- Array#[]
     array[index]                -> obj      or nil
     array[start, length]        -> an_array or nil
     array[range]                -> an_array or nil
     array.slice(index)          -> obj      or nil
     array.slice(start, length)  -> an_array or nil
     array.slice(range)          -> an_array or nil
------------------------------------------------------------------------
     Element Reference---Returns the element at index, or returns a 
     subarray starting at start and continuing for length elements, or 
     returns a subarray specified by range. Negative indices count 
     backward from the end of the array (-1 is the last element). 
     Returns nil if the index (or starting index) are out of range.

        a = [ "a", "b", "c", "d", "e" ]
        a[2] +  a[0] + a[1]    #=> "cab"
        a[6]                   #=> nil
        a[1, 2]                #=> [ "b", "c" ]
        a[1..3]                #=> [ "b", "c", "d" ]
        a[4..7]                #=> [ "e" ]
        a[6..10]               #=> nil
        a[-3, 3]               #=> [ "c", "d", "e" ]
        # special cases
        a[5]                   #=> nil
        a[6, 1]                #=> nil
        a[5, 1]                #=> []
        a[5..10]               #=> []
person Paige Ruten    schedule 29.03.2009
comment
почему [5, 1] ​​отличается от [6, 1]? - person dertoni; 01.03.2011
comment
@dertoni: stackoverflow.com/questions/3219229/ - person michelpm; 08.12.2011
comment
a[2..-1], чтобы перейти от третьего элемента к последнему. a[2...-1], чтобы перейти от третьего элемента ко второму последнему элементу. - person Clever Programmer; 24.11.2015
comment
@Rafeh приветствует, интересно, как работает эта хлам, -1 сделал свое дело - person Ben Affleck; 02.12.2015
comment
Синтаксис @CleverProgrammer намного ближе к Python, чем принятый ответ. Я люблю Ruby, но должен сказать, что синтаксис Python короче и понятнее. В качестве бонуса можно указать шаг: range(10)[:5:-1] - person Eric Duminil; 02.12.2016

Если вы хотите разделить / вырезать массив по индексу i,

arr = arr.drop(i)

> arr = [1,2,3,4,5]
 => [1, 2, 3, 4, 5] 
> arr.drop(2)
 => [3, 4, 5] 
person Lenin Raj Rajasekaran    schedule 13.02.2014

Для этого можно использовать slice ():

>> foo = [1,2,3,4,5,6]
=> [1, 2, 3, 4, 5, 6]
>> bar = [10,20,30,40,50,60]
=> [10, 20, 30, 40, 50, 60]
>> half = foo.length / 2
=> 3
>> foobar = foo.slice(0, half) + bar.slice(half, foo.length)
=> [1, 2, 3, 40, 50, 60]

Кстати, насколько мне известно, «списки» Python просто эффективно реализованы динамически растущими массивами. Вставка в начале находится за O (n), вставка в конце амортизируется за O (1), произвольный доступ - за O (1).

person Manuel    schedule 29.03.2009
comment
Вы хотите использовать массив столбцов во втором срезе? - person Samuel; 30.03.2009
comment
К вашему сведению: slice!() не изменяет массив на месте, а скорее удаляет элементы, заданные индексом (необязательно до элементов длины) или диапазоном. согласно ruby-doc.org/core-2.2 .3 / Array.html # method-i-slice-21 - person Joshua Pinter; 26.08.2015
comment
@joshuapinter Спасибо себе! Меня это только что укусило (опять же, видимо). - person Joshua Pinter; 09.03.2021

другой способ - использовать метод диапазона

foo = [1,2,3,4,5,6]
bar = [10,20,30,40,50,60]
a = foo[0...3]
b = bar[3...6]

print a + b 
=> [1, 2, 3, 40, 50 , 60]
person user3449311    schedule 30.01.2015

Мне нравятся диапазоны для этого:

def first_half(list)
  list[0...(list.length / 2)]
end

def last_half(list)
  list[(list.length / 2)..list.length]
end

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

В приведенном выше примере средний элемент будет последовательно помещаться во второй половине.

person labyrinth    schedule 23.03.2018
comment
Вы можете использовать (list.length / 2.0).ceil, чтобы последовательно помещать средний элемент в первую половину, если вам это нужно. - person Sorashi; 03.05.2019