Bagaimana cara mengembalikan bagian dari sebuah array di Ruby?


125

Dengan daftar di Python, saya dapat mengembalikan sebagian darinya menggunakan kode berikut:

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

Karena Ruby melakukan segalanya dalam array, saya bertanya-tanya apakah ada yang mirip dengan itu.

Jawaban:


192

Ya, Ruby memiliki sintaks pengiris larik yang sangat mirip dengan Python. Berikut adalah ridokumentasi untuk metode indeks 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
mengapa [5, 1] ​​berbeda dari [6, 1]?
dertoni


25
a[2..-1]untuk berpindah dari elemen ketiga ke elemen terakhir. a[2...-1]untuk berpindah dari elemen ketiga hingga elemen terakhir kedua.
Programmer Cerdas

1
@Rafeh bersorak, bertanya-tanya bagaimana sampah ini bekerja, -1 berhasil
Ben Sinclair

Sintaks @CleverProgrammer lebih mirip dengan Python daripada jawaban yang diterima. Saya suka Ruby, tetapi saya harus mengatakan bahwa sintaks Python lebih pendek dan lebih jelas. Sebagai bonus, dimungkinkan untuk menentukan langkahnya:range(10)[:5:-1]
Eric Duminil

27

Jika Anda ingin membagi / memotong array pada indeks i,

arr = arr.drop(i)

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

17

Anda dapat menggunakan slice () untuk ini:

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

By the way, sejauh pengetahuan saya, "daftar" Python hanya diimplementasikan secara efisien array yang tumbuh secara dinamis. Penyisipan di awal dalam O (n), penyisipan di akhir diamortisasi O (1), akses acak O (1).


Apakah Anda bermaksud menggunakan bar array di potongan kedua?
Samuel

FYI: slice!()tidak mengubah larik pada tempatnya, melainkan, "Menghapus elemen yang diberikan oleh indeks (opsional hingga elemen panjang) atau rentang." per ruby-doc.org/core-2.2.3/Array.html#method-i-slice-21
Joshua Pinter

7

cara lain adalah dengan menggunakan metode jangkauan

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 Rentang Tanpa Awal / Tanpa Akhir

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

Saya suka rentang untuk ini:

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

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

Namun, berhati-hatilah dengan apakah titik akhir termasuk dalam rentang Anda. Ini menjadi kritis pada daftar panjang yang aneh di mana Anda harus memilih di mana Anda akan mematahkan bagian tengah. Jika tidak, Anda akan menghitung dua kali elemen tengah.

Contoh di atas akan secara konsisten menempatkan elemen tengah di paruh terakhir.


Anda dapat menggunakan (list.length / 2.0).ceiluntuk menempatkan elemen tengah secara konsisten di paruh pertama jika Anda membutuhkannya.
Sorashi
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.