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.

Christian Stade-Schuldt
quelle

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

Manuel
quelle
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]
user3449311
quelle
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"]
PGill
quelle
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.

Labyrinth
quelle
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