Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: for(x in arr)
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
batman
Witam

Mam problem z tablicą asocjacyjną. Tablica ta ma następującą strukturę:

Kod
arr = new Array();
arr["pole1"] = "string";
arr["pole2"] = "string_2";


Wcześniej przy pomocy prototype zdefiniowałem dodatkowe funkcje dla obiektu Array. Pierwsza to find, a druga to remove.

Problem pojawia się w momencie, gdy próbuję uzyskać dostęp do elementów tablicy przy pomocy For...In.

Kod
for(xx in arr) {
    alert(xx);
}


Pętla ta dołącza do tablicy arr zdefinowane przeze mnie funkcje i zamiast wyświetlić dwa alerty ("string" i "string_2"), wyświetla cztery ("find", "remove", "string" i "string_2").

Co jest tego przyczyną i w jaki sposób można temu zaradzić?
siemakuba
Cytat
Pętla ta dołącza do tablicy arr zdefinowane przeze mnie funkcje
nie bardzo rozumiem ten fragment. Skoro dodałeś wcześniej dodatkowe metody do obiektu Array, to czemu jeszcze dołączasz je tutaj.

Poza tym, to co pokazałeś to nie jest tablica asocjacyjna. W JS nie ma czegoś takiego jak tablice asocjacyjne.
To co widzimy w twoim przykładzie, to dodanie do obiektu arr właściwości pole1 i pole2.
Nie są to elementy tablicy, ale właścwości obiektu.

Jeżeli chcesz osiągnąć coś na wzór tablicy asocjacyjnej, powinieneś posłużyć się obiektem.

Kod
var assocArray = new Object;
assocArray['pole1'] = 'string';

// lub

var assocArray = new Object;
assocArray.pole1 = 'string';

// lub
var assocArray = {'pole1':'string', 'pole2':'string2'};


zajrze jeszcze wieczorem w domu ściągawek, ale z tego co pamiętam, to właśnie tak to wygląda.

pozdr.
batman
Mniejsza z nazewnictwem winksmiley.jpg
Problemem jest to, że w petli For...In oprócz elementów tablicy wyświetlane są również zdefiniowane przeze mnie funkcje.
siemakuba
Cytat
Mniejsza z nazewnictwem
Problemem jest to, że w petli For...In oprócz elementów tablicy wyświetlane są również zdefiniowane przeze mnie funkcje.
Proszę, czytaj ze zrozumieniem. Nie o nazewnictwo tu chodzi, ale o to co tam wytworzyłeś. I nawet gdyby nazwywało się tak jak sobie zarzyczysz, będzie ciągle nie tym co chcesz osiągnąć.

Napisałem przecież, że nie dodałeś żadnego elementu do tablicy. Nadałeś tablicy nowe właściwości. Nie tablicy jako takiej, ale obiektowi arr.

W JS wszystko jest obiektem, więc twój obiekt arr reprezentuje tablicę. Ta tablica jest jednak pusta, bo nie dałeś jej żadnych wartości. Dziwisz się się, że obok właściwości pole1 i pole2 widzisz też nazwy metod. Tak, widzisz je, bo zarówno jedne jak i drugie są właściwościami obiektu arr.

Prosty test - alert(arr.length); - i co? zero? widzisz, jednak nie ma wartości.

Jeszcze raz - albo będziesz miał tablicę, albo będziesz miał obiekt. Jak chcesz coś na kształt tablicy asocjacyjnej - zbuduj obiekt i nadaj mu właściwości jak to robisz teraz.

Jak już bardzo chcesz mieć to w ten sposób i upierać się że to jest tablica asocjacyjna, ale nie chcesz widzieć swoich metod obok właściwości, zrób tak:
Kod
for(xx in arr)
{
    if (typeof(arr[xx]) == 'function')
    {    continue;
    }
   alert(xx);
}


P.S. przeczytaj jeszcze raz co napisałem, ze zrozumieniem tym razem :)

pozdr.
batman
Rozumiem co napisałeś i wiem, że w JS nie ma czegoś takiego jak tablice asocjacyjne. Chodzi mi tylko o to, czy można bez if wyświetlić zawartość "tablicy"?
siemakuba
hehe :) Przepraszam cię bardzo, ale jednak nie rozumiesz :)
Cytat
Chodzi mi tylko o to, czy można bez if wyświetlić zawartość "tablicy"?
Po raz trzeci i ostatni napiszę ci, że tablica, którą stworzyłeś nie ma żadnej zawartości. Jak chcesz ją więc wyświetlać?

Masz obiekt i masz jego właściwości. Właściwości mogą być zwykłymi danymi (towje pola pole1 i pole2) i mogą być też wskaźnikami do funkcji. (twoje metody dodane za pomocą prototype). Iterując przez ten obiekt za pomocą pętli for...in iterujesz przez jego właściwości, bo sama tablica jest pusta.

finito.
pozdr.
batman
Będę się jednak upierał, że rozumiem winksmiley.jpg

W każdym bądź razie dziękuję za czas i cierpliwość. Pozostawię kod bez zmian i będę dalej szukał rozwiązania.
siemakuba
Hehe, może być też tak, że ja nie zrozumiałem do końca co chcesz osiągnąć. Nie wiem czy to się nada do twoich potrzeb (nie wiem czy będzie grało z dodanymi przez prototype metodami), ale wpadło mi do głowy takie rozwiązanie:

1. Modyfikujesz swoje prototype-metody tak, aby nie działały na samym obiekcie "tablica" ale na obiekcie zawartym jako składowa obiektu "tablica".

2. Tworzysz obiekt "tablica", i dodajesz mu składowa o nazwie "values" i typie Array.

3. Twoje prototype-metody pracują na danych w tablicy "tablica".values

4. Za pomocą for...in iterujesz przez "tablica".values

przykład:
Kod
Array.prototype.find = function()
{
    // tu szukasz, ale nie w "this", ale w "this.values"
}

(...)

var arr = new Array;
arr.values = new Array;

arr.find('wanda'); // jest metodą obiektu "arr", ale działa na wartościach trzymanych w "[i]podobiekcie[/i]" arr.values


edit:
no i oczywiści wartości dodajesz jako arr.values[0] = 'wanda';

damn... zamotałem chyba :)
pozdr.
batman
Niestey nie moge zmodyfikować prototype, ponieważ są one używane przez kilka innych obiektów. Pozostanę przy sprawdzaniu, czy to co mi zwraca For...In jest funkcją. Jeszcze raz dziękuje za pomoc winksmiley.jpg
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.