Come restituire una parte di un array in Ruby?


125

Con un elenco in Python posso restituirne una parte usando il seguente codice:

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

Dal momento che Ruby fa tutto negli array, mi chiedo se ci sia qualcosa di simile a quello.

Risposte:


192

Sì, Ruby ha una sintassi molto simile all'array-slicing di Python. Ecco la ridocumentazione per il metodo dell'indice di array:

--------------------------------------------------------------- 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
perché un [5, 1] ​​è diverso da un [6, 1]?
Dertoni,


25
a[2..-1]per passare dal terzo elemento all'ultimo. a[2...-1]per passare dal terzo elemento fino al secondo ultimo elemento.
Clever Programmer,

1
@Rafeh salute, mi chiedevo come funziona questa spazzatura, -1 ha fatto il trucco
Ben Sinclair,

La sintassi di @CleverProgrammer è molto più vicina a Python rispetto alla risposta accettata. Adoro Ruby, ma devo dire che la sintassi di Python è più breve e più chiara. Come bonus, è possibile specificare il passaggio:range(10)[:5:-1]
Eric Duminil,

27

Se si desidera dividere / tagliare l'array su un indice i,

arr = arr.drop(i)

> arr = [1,2,3,4,5]
 => [1, 2, 3, 4, 5] 
> arr.drop(2)
 => [3, 4, 5] 

17

Puoi usare slice () per questo:

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

A proposito, per quanto ne sappia, gli "elenchi" di Python sono implementati in modo efficace solo in modo dinamico. L'inserimento all'inizio è in O (n), l'inserimento alla fine è ammortizzato O (1), l'accesso casuale è O (1).


Intendi usare l'array di barre nella seconda porzione?
Samuel,

Cordiali saluti: slice!()non modifica l'array in atto, piuttosto "Elimina gli elementi forniti da un indice (opzionalmente fino ad elementi di lunghezza) o da un intervallo". per ruby-doc.org/core-2.2.3/Array.html#method-i-slice-21
Joshua Pinter

7

un altro modo è usare il metodo 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 Range Beginless / Endless

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

Mi piacciono le gamme per questo:

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

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

Tuttavia, prestare molta attenzione al fatto che l'endpoint sia incluso nell'intervallo. Questo diventa fondamentale in un elenco di lunghezze dispari in cui devi scegliere dove spezzare il centro. Altrimenti finirai per contare due volte l'elemento centrale.

L'esempio sopra inserirà costantemente l'elemento centrale nell'ultima metà.


Puoi usarlo (list.length / 2.0).ceilper mettere costantemente l'elemento centrale nella prima metà se ne hai bisogno.
Sorashi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.