Comment retourner une partie d'un tableau dans Ruby?

125

Avec une liste en Python, je peux en renvoyer une partie en utilisant le code suivant:

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

Puisque Ruby fait tout dans des tableaux, je me demande s'il y a quelque chose de similaire.

Christian Stade-Schuldt
la source

Réponses:

192

Oui, Ruby a une syntaxe de découpage de tableau très similaire à Python. Voici la ridocumentation de la méthode d'index de tableau:

--------------------------------------------------------------- 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]               #=> []
Jeremy Ruten
la source
5
pourquoi un [5, 1] ​​est-il différent d'un [6, 1]?
dertoni
25
a[2..-1]pour passer du 3ème élément au dernier. a[2...-1]pour passer du 3ème élément à l'avant-dernier élément.
Programmeur intelligent
1
@Rafeh cheers, je me suis demandé comment cette ordure fonctionne, -1 a fait l'affaire
Ben Sinclair
La syntaxe de @CleverProgrammer est beaucoup plus proche de Python que la réponse acceptée. J'adore Ruby, mais je dois dire que la syntaxe de Python est plus courte et plus claire. En prime, il est possible de préciser l'étape:range(10)[:5:-1]
Eric Duminil
27

Si vous voulez diviser / couper le tableau sur un index i,

arr = arr.drop(i)

> arr = [1,2,3,4,5]
 => [1, 2, 3, 4, 5] 
> arr.drop(2)
 => [3, 4, 5] 
Lénine Raj Rajasekaran
la source
17

Vous pouvez utiliser slice () pour cela:

>> 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]

Au fait, à ma connaissance, les "listes" Python sont simplement implémentées de manière efficace dans des tableaux à croissance dynamique. L'insertion au début est en O (n), l'insertion à la fin est amortie O (1), l'accès aléatoire est O (1).

Manuel
la source
Voulez-vous utiliser le tableau de barres dans la deuxième tranche?
Samuel
FYI: slice!()ne modifie pas le tableau en place, mais "supprime le ou les éléments donnés par un index (éventuellement jusqu'à des éléments de longueur) ou par une plage." par ruby-doc.org/core-2.2.3/Array.html#method-i-slice-21
Joshua Pinter
7

une autre façon est d'utiliser la méthode range

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]
user3449311
la source
3

Ruby 2.6 Gammes sans début / sans fin

(..1)
# or
(...1)

(1..)
# or
(1...)

[1,2,3,4,5,6][..3]
=> [1, 2, 3, 4]

[1,2,3,4,5,6][...3]
 => [1, 2, 3]

ROLES = %w[superadmin manager admin contact user]
ROLES[ROLES.index('admin')..]
=> ["admin", "contact", "user"]
PGill
la source
2

J'aime les gammes pour ça:

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

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

Cependant, soyez très prudent si le point de terminaison est inclus dans votre plage. Cela devient critique sur une liste de longueur impaire où vous devez choisir où vous allez casser le milieu. Sinon, vous finirez par compter deux fois l'élément du milieu.

L'exemple ci-dessus placera systématiquement l'élément du milieu dans la dernière moitié.

labyrinthe
la source
Vous pouvez utiliser (list.length / 2.0).ceilpour placer systématiquement l'élément du milieu dans la première moitié si vous en avez besoin.
Sorashi