Wie kann man einen Teil eines Arrays in Ruby zurückgeben?


125

Mit einer Liste in Python kann ich einen Teil davon mit dem folgenden Code zurückgeben:

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

Da Ruby alles in Arrays macht, frage ich mich, ob es so etwas gibt.

Antworten:


192

Ja, Ruby hat eine sehr ähnliche Array-Slicing-Syntax wie Python. Hier ist die riDokumentation für die Array-Indexmethode:

--------------------------------------------------------------- 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
Warum unterscheidet sich ein [5, 1] ​​von einem [6, 1]?
Dertoni


25
a[2..-1]um vom 3. zum letzten Element zu gelangen. a[2...-1]um vom 3. Element zum vorletzten Element zu gelangen.
Clever Programmer

1
@ Rafeh Prost, habe mich gefragt, wie dieser Müll funktioniert, -1 hat den Trick gemacht
Ben Sinclair

Die @ CleverProgrammer-Syntax ist Python viel näher als die akzeptierte Antwort. Ich liebe Ruby, aber ich muss sagen, dass Pythons Syntax kürzer und klarer ist. Als Bonus ist es möglich, den Schritt anzugeben:range(10)[:5:-1]
Eric Duminil

27

Wenn Sie das Array auf einem Index i teilen / schneiden möchten,

arr = arr.drop(i)

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

17

Sie können dazu Slice () verwenden :

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

Übrigens, nach meinem besten Wissen sind Python- "Listen" nur effizient implementierte dynamisch wachsende Arrays. Die Einfügung am Anfang erfolgt in O (n), die Einfügung am Ende wird in O (1) abgeschrieben, der Direktzugriff ist O (1).


Wollen Sie das Balkenarray im zweiten Slice verwenden?
Samuel

Zu Ihrer Information: slice!() Ändert das Array nicht an Ort und Stelle, sondern "löscht die Elemente, die durch einen Index (optional bis zu Länge Elemente) oder durch einen Bereich angegeben werden." per ruby-doc.org/core-2.2.3/Array.html#method-i-slice-21
Joshua Pinter

7

Eine andere Möglichkeit ist die Verwendung der Bereichsmethode

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 Beginless / Endless Ranges

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

Ich mag Bereiche dafür:

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

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

Seien Sie jedoch sehr vorsichtig, ob der Endpunkt in Ihrem Bereich enthalten ist. Dies wird bei einer Liste mit ungerader Länge kritisch, bei der Sie auswählen müssen, wo Sie die Mitte durchbrechen möchten. Andernfalls wird das mittlere Element doppelt gezählt.

Im obigen Beispiel wird das mittlere Element konsistent in die letzte Hälfte eingefügt.


Sie können verwenden (list.length / 2.0).ceil, um das mittlere Element in der ersten Hälfte konsistent zu platzieren, wenn Sie dies benötigen.
Sorashi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.