¿Cómo devolver una parte de una matriz en Ruby?


125

Con una lista en Python, puedo devolver una parte usando el siguiente código:

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

Como Ruby hace todo en matrices, me pregunto si hay algo similar a eso.

Respuestas:


192

Sí, Ruby tiene una sintaxis de corte de matriz muy similar a Python. Aquí está la ridocumentación para el método de índice de matriz:

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

55
¿Por qué es un [5, 1] ​​diferente de un [6, 1]?
dertoni


25
a[2..-1]para pasar del tercer elemento al último. a[2...-1]para ir desde el tercer elemento hasta el segundo último elemento.
Programador inteligente

1
@Rafeh aplaude, preguntándose cómo funciona esta basura, -1 hizo el truco
Ben Sinclair

La sintaxis de @CleverProgrammer está mucho más cerca de Python que la respuesta aceptada. Amo a Ruby, pero debo decir que la sintaxis de Python es más corta y clara. Como beneficio adicional, es posible especificar el paso:range(10)[:5:-1]
Eric Duminil

27

Si desea dividir / cortar la matriz en un índice i,

arr = arr.drop(i)

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

17

Puede usar slice () para esto:

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

Por cierto, que yo sepa, las "listas" de Python se implementan de manera eficiente en forma dinámica. La inserción al principio está en O (n), la inserción al final se amortiza O (1), el acceso aleatorio es O (1).


¿Te refieres a usar la matriz de barras en la segunda rebanada?
Samuel

FYI: slice!()no modifica la matriz en su lugar, sino que "elimina los elementos dados por un índice (opcionalmente hasta elementos de longitud) o por un rango". por ruby-doc.org/core-2.2.3/Array.html#method-i-slice-21
Joshua Pinter el

7

otra forma es usar el método de rango

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 Rangos sin fin / sin 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

Me gustan los rangos para esto:

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

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

Sin embargo, tenga mucho cuidado sobre si el punto final está incluido en su rango. Esto se vuelve crítico en una lista de longitud impar donde necesita elegir dónde va a romper el medio. De lo contrario, terminarás contando dos veces el elemento del medio.

El ejemplo anterior consistentemente pondrá el elemento del medio en la última mitad.


Puede usar (list.length / 2.0).ceilpara poner consistentemente el elemento del medio en la primera mitad si lo necesita.
Sorashi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.