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.

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]               #=> []

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] 

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).


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]

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

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é.


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.