Làm thế nào để trả về một phần của một mảng trong Ruby?


125

Với một danh sách trong Python tôi có thể trả về một phần của nó bằng mã sau:

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

Vì Ruby làm mọi thứ trong mảng, tôi tự hỏi liệu có thứ gì tương tự như vậy không.

Câu trả lời:


192

Có, Ruby có cú pháp cắt mảng rất giống với Python. Dưới đây là ritài liệu cho phương pháp chỉ mục mảng:

--------------------------------------------------------------- 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
tại sao [5, 1] ​​khác với [6, 1]?
dertoni


25
a[2..-1]để có được từ yếu tố thứ 3 đến yếu tố cuối cùng. a[2...-1]để có được từ phần tử thứ 3 cho đến phần tử cuối cùng thứ hai.
Lập trình viên thông minh

1
@Rafeh chúc mừng, đã tự hỏi làm thế nào rác này hoạt động, -1 đã thực hiện mánh khóe
Ben Sinclair

Cú pháp @CleverProgrammer gần với Python hơn câu trả lời được chấp nhận. Tôi yêu Ruby, nhưng tôi phải nói rằng cú pháp của Python ngắn hơn và rõ ràng hơn. Như một phần thưởng, có thể chỉ định bước:range(10)[:5:-1]
Eric Duminil

27

Nếu bạn muốn tách / cắt mảng trên chỉ mục i,

arr = arr.drop(i)

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

17

Bạn có thể sử dụng lát () cho việc này:

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

Nhân tiện, theo hiểu biết tốt nhất của tôi, "danh sách" Python chỉ được triển khai một cách hiệu quả các mảng phát triển động. Chèn ở đầu là O (n), chèn ở cuối được khấu hao O (1), truy cập ngẫu nhiên là O (1).


Bạn có nghĩa là sử dụng mảng thanh trong lát thứ hai?
Samuel

FYI: slice!()không sửa đổi mảng tại chỗ, thay vào đó, nó "Xóa (các) phần tử được cung cấp bởi một chỉ mục (tùy chọn lên đến các phần tử chiều dài) hoặc theo một phạm vi." mỗi ruby-doc.org/core-2.2.3/Array.html#method-i-slice-21
Joshua Pinter

7

một cách khác là sử dụng phương thức phạm vi

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 Phạm vi vô tận / vô tận

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

Tôi thích phạm vi cho điều này:

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

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

Tuy nhiên, hãy thật cẩn thận về việc liệu điểm cuối có được bao gồm trong phạm vi của bạn hay không. Điều này trở nên quan trọng trong một danh sách có độ dài lẻ, nơi bạn cần chọn nơi bạn sẽ phá vỡ giữa chừng. Nếu không, bạn sẽ kết thúc hai lần đếm phần tử ở giữa.

Ví dụ trên sẽ liên tục đưa phần tử ở giữa vào nửa cuối.


Bạn có thể sử dụng (list.length / 2.0).ceilđể liên tục đặt phần tử ở giữa trong nửa đầu nếu bạn cần.
Sorashi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.