Operacje na tabelach wielowymiarowych

ok, po pierwsze nie rozumiem tej składni: a ||= []
skąd Wy czerpiecie takie czarodziejskie formułki? :wink:
co do dodawania elementu do tablicy jednowymiarowej to radzę sobie w miarę sprawnie,
mam problem z dodaniem elementu do tablicy z 3 wymiarami, tzn:

@tab[x][y][z]

mam wartości “x” oraz “y” i teraz chciałbym dodawać kolejne wartości do tablicy nie podając wartości indeksu “z”
obrazowo rzecz ujmując: na “skrzyżowaniu” wiersza i kolumny umieszczam tablice i to do tej tablicy chciałbym dodawać elementy

[quote=jjc]ok, po pierwsze nie rozumiem tej składni: a ||= []
skąd Wy czerpiecie takie czarodziejskie formułki? ;)[/quote]
a ||= []

przypisze do a pustą tablicę tylko jeśli a ma pustą wartość (nil)
a ||= b oznacza “przypisz b do a tylko gdy a == nil”

[quote=jjc]co do dodawania elementu do tablicy jednowymiarowej to radzę sobie w miarę sprawnie,
mam problem z dodaniem elementu do tablicy z 3 wymiarami, tzn:

@tab[x][y][z]

mam wartości “x” oraz “y” i teraz chciałbym dodawać kolejne wartości do tablicy nie podając wartości indeksu “z”
obrazowo rzecz ujmując: na “skrzyżowaniu” wiersza i kolumny umieszczam tablice i to do tej tablicy chciałbym dodawać elementy[/quote]

@tab[x][y][] << element_ktory_chcesz_dodać

<< to metoda instancji klasy Array która po prostu dodaje kolejny element do tablicy.

Najlepiej zapoznaj się z całym zestawem metod dla Array i Enumerable

dzięki za odpowiedź! była naprawdę pomocna, tak samo jak linki :slight_smile:
jednak robiąc tak:

@tab[x][y] = [] @tab[x][y][] << nowy_element
dostaje błąd:

 wrong number of arguments (0 for 1) (ArgumentError)

ale wersja:

@tab[x][y] = [] @tab[x][y] << nowy_element
działa mi prawidłowo

jednak narodziło mi się jeszcze jedno pytanie:
jak zaznaczyć aby Ruby dodawał tablicę @tab[x][y] = []
TYLKO w przypadku gdy jej tam jeszcze nie ma (w przeciwnym wypadku niech tylko doda element do już istniejącej tablicy)?
czy jest jakiś sposób ładniejszy od IFa?

[quote=radarek]a = Array.new { [] } a << 2 p a
Pick your favourite.[/quote]
Pomyliło mi się z Hashem, niestety to nie zadziała.

[quote=hosiawak]a ||= []
przypisze do a pustą tablicę tylko jeśli a ma pustą wartość (nil)[/quote]
Lub false.

[quote=jjc]jednak robiąc tak:

@tab[x][y] = [] @tab[x][y][] << nowy_element
dostaje błąd:

 wrong number of arguments (0 for 1) (ArgumentError)

[/quote]
Czemu uparcie próbujesz przenieść phpowe array[] do rubiego?
Błąd pojawia się ponieważ w rubym [] jest zwykłą metodą (lub też literał tablicy, zależy od kontekstu użycia). Ponieważ oczekuje ona parametr, a Ty go nie podajesz to pojawia się błąd o złej liczbie argumentów.

[quote=jjc]ale wersja:

@tab[x][y] = [] @tab[x][y] << nowy_element
działa mi prawidłowo[/quote]
Dlatego, że w pierwszej linii przypisałeś pod @tab[x][y] pustę tablicę ([]). W drugiej linii do tej pustej tablicy (@tab[x][y]) dołączasz (<<) element (nowy_element).

[quote=jjc]jednak narodziło mi się jeszcze jedno pytanie:
jak zaznaczyć aby Ruby dodawał tablicę @tab[x][y] = []
TYLKO w przypadku gdy jej tam jeszcze nie ma (w przeciwnym wypadku niech tylko doda element do już istniejącej tablicy)?
czy jest jakiś sposób ładniejszy od IFa?[/quote]
Odpowiedź już pojawiła się kilka razy w tym temacie:

[code]zmienna ||= wartość
a = nil

a ||= []
a << 1
p a
a ||= []
a << 2
p a

lub krócej

(a ||= []) << 3
p a[/code]

Dzięki Radku!
trzymałem się konstrukcji:

  @tab[x][y][] << element

częściowo z powodu starych przyzwyczajeń,
a częściowo dlatego że post wyżej hosiawak powiedział że mogę tak zrobić :wink:
dzięki także za łopatologiczne tłumaczenie składni ||=
ruby zaczyna wyglądać coraz bardziej kusząco :slight_smile:

EDIT:
Jak wyszperać z tablicy wielowymiarowej ten wiersz którego pierwszy element powtarza się co najmniej n razy?
w tym przykładzie dwa razy, wiersz o indeksie 3 tzn. [2, [2], [2]]

[nil, a, b ] [0, [1], [2]] [1, [1], [3]] [2, [2], [2]] [3, [2], [3]]
domyślam się że mogło by być to coś z .flatten a później może jakoś z .find jednak nie wiem jak to zrobić a’la “Ruby style” :wink:

Moze tak:

[code]>> a
=> [[0, [2, 2, 3, 4]], [1, [3, 4, 5, 6]], [2, [2, 2, 2, 2]], [5, [5, 5, 5, 2]]]

a.select { |e| (e.flatten.select { |x| x == e[0] }.size) >= 2 }
=> [[2, [2, 2, 2, 2]], [5, [5, 5, 5, 2]]]

[/code]

hm… kod a = [[0, [2, 2, 3, 4]], [1, [3, 4, 5, 6]], [2, [2, 2, 2, 2]], [5, [5, 5, 5, 2]]] a.select { |e| (e.flatten.select { |x| x == e[0] }.size) >= 2 }
zwraca mi 1 a powinien chyba zwracać wszystko tylko nie to :confused:

Dlaczego ?

>> [[0, [2, 2, 3, 4]], [1, [3, 4, 5, 6]], [2, [2, 2, 2, 2]], [5, [5, 5, 5, 2]]].select { |e| (e.flatten.select { |x| x == e[0] }.size) >= 2 } => [[2, [2, 2, 2, 2]], [5, [5, 5, 5, 2]]]
taki masz wynik ?

w tym zapytaniu tak :stuck_out_tongue:
tyle że chciałem otrzymać tablice z samymi wartościami z pierwszego indeksu czyli [2, 5]