2013-07-18 12 views
5

szukam elegancki sposób na partycje tablicę za pomocą indeksu w Rubytablica partycji za pomocą indeksu w Ruby

np

["a","b",3,"c",5].partition_with_index(2) 
    => [["a","b",3],["c",5]] 

Dotychczas najlepiej, że mogę myśleć jest za pomocą poniżej

["a","b",3,"c",5].partition.each_with_index{|val,index| index <= 2} 
    => [["a","b",3],["c",5]] 

Czy istnieje inny elegancki sposób, aby to osiągnąć?

Dzięki!

Odpowiedz

9

można zrobić:

["a","b",3,"c",5].partition.with_index { |_, index| index <= 2 } 

Po @ poradę toro2k, myślę, że jest to lepsze rozwiązanie, ponieważ łączysz dwa modele: Enumerators, aby uzyskać pożądane wyjście.

Jeśli nie przekazujesz bloku kodu do partition, to zwraca on obiekt Enumerator. Enumerators mieć metodę with_index, która będzie utrzymywać bieżący indeks pętli.

+0

myślę, że należy rozwinąć dlaczego jest to lepsze rozwiązanie niż proponowane przez PO. – toro2k

+0

@ toro2k myślę, że to trochę lepiej :) – NicoSantangelo

2

Można to zrobić, ale nie wiem, czy to eleganckie czy nie:

a = ["a","b",3,"c",5] 
index = 2 
[a[0..index], a[index+1..-1]] 

Dzięki

6

Dlaczego nie używacie array.slice!

tablicy # kawałek! Usuwa element (y) podany przez indeks (opcjonalnie do elementów długości) lub zakres.

> a = ['a', 'b', 'c', 5] 
> b = a.slice! 0, 2 # => ['a', 'b'] 
> a # => ['c', 5] 

W twoim przypadku,

> [a.slice!(0, index), a] 
+1

Aby osiągnąć ten sam rezultat jak w PO: '> a = [ 'a', 'b', 3 'c', 5]' '> [a.slice! (0,2), a] # => [[" a "," b ", 3], [" c ", 5]]' – cassianoleal

+0

@ cbl: yup. zapomniałem o tym. Dodajecie go przez edycję? –

+0

Myślę, że jest to mniej czytelne na pierwszy rzut oka, ale jest fajne, ale – NicoSantangelo

4

Można użyć przeliczalna za take i drop metody:

a = ["a","b",3,"c",5] 
[a.take(3), a.drop(3)] # => [["a", "b", 3], ["c", 5]] 

zrobiłem Enumerable quick reference sheet warto skonsultować się z pytaniami jak ten.

0

dla konkretnego przypadku „pyper” gem jest użyteczny:

require 'pyper' # gem install pyper if necessary 
include Pyper 

ary = ["a", "b", 3, "c", 5] 
ary.τ3τ #=> ["a", "b", 3] 
ary.τfτ #=> ["c", 5] 

Działa tylko łatwo na małym n (liczba posiekane-off elementów), ale Pyper zapewnia wiele innych często spotykanych zadań na zbiorach. Zainspirowały go funkcje LISPa car i cdr (see details by an anonymous donor), a litery można łączyć ze sobą w ciąg sterujący, trochę jak w APL.Grecki tau (τ) jest używany do określenia metod zamiast c i r, więc car, cdr stać τaτ, τdτ:

ary.τaτ #=> "a" 
ary.τdτ #=> ["b", 3, "c", 5] 
# Instead of τfτ, one can write 
ary.τdddτ #=> ["c", 5] 
etc. 
0

można spróbować poniżej:

a = ["a","b",3,"c",5] 
par = a.slice_before(sum: -2) do |elem, state| 
    state[:sum] += 1 
    state[:sum] == 2 
end.to_a 
par 
# => [["a", "b", 3], ["c", 5]] 
Powiązane problemy