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.

Christian Stade-Schuldt
sumber

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]               #=> []
Jeremy Ruten
sumber
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] 
Lenin Raj Rajasekaran
sumber
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).

Manuel
sumber
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]
pengguna3449311
sumber
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"]
PGill
sumber
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.

labirin
sumber
Anda dapat menggunakan (list.length / 2.0).ceiluntuk menempatkan elemen tengah secara konsisten di paruh pertama jika Anda membutuhkannya.
Sorashi