Rekursywne połączenie dwóch hashy

0

Mam dwa drzewiaste hashe z danymi, które chciałbym połączyć. Do połączenia użyję metody concat, ale chciałbym, żeby to wyglądało tak, że w drugim hashu zmieniam najpierw wartości na np. 'unknown' i po połączeniu dwóch hashy dane które nie są obecne w pierwszym hashu będą Od razu widoczne. Nie znam tylko sposobu na szybką rekursywną zmianę wartości hasha. Zna ktoś sposób na szybkie (krótkie w kodzie) rozwiązaniem tego problemu

0

Hashy? Concat?

Zdaje się, że nie operujesz do końca nazewnictwem poprawnym z punktu wiedzenia JavaScriptu. Ciężko mi zrozumieć o co Ci chodzi. Możesz dać kod?

W JavaScripcie mówi się czasem, że obiekty to tablice mieszające, z ang. hashtable (lub czasem: hashmap). Nie są to oczywiście "hashe", bo hash to co innego. Rozumiem, że chodziło Ci o hashmapy.

Nawet wtedy jednak nie jest zupełną prawdą to, że obiekty w JavaScripcie mogą tak zupełnie bezpośrednio, super łatwo służyć za hashmapy. W JS-ie, kluczami obiektów są tylko stringi; hash może być liczony wewnętrznie przez przeglądarkę, ale ze stringów. Kluczami w obiektach JS nie mogą być obiekty.

Obiekty w JS nie mają metody concat(). Metoda ta jest charakterystyczna dla tablic. Tablice to też obiekty, ale klucze będące liczbami całkowitymi traktowane są w nich w specjalny sposób. Własność .length też. Metoda concat() operuje wyłącznie na kluczach będących liczbami, czyli po prostu na elementach typowo tablicowych. Ciężko więc w jakikolwiek sposób łączyć ją z hashem czy hashmapą.

W świetle tego wszystkiego, Twój post wydaje mi się trochę masłem maślanym. Może są w nim skróty myślowe, które są de facto błędami i które ciężko mi zrozumieć. A może po prostu czegoś nie kminię.

Może się zdarzyć, że w ogóle nie będziesz musiał łączyć "hashmap". W takim przypadku pomocne może być dziedziczenie prototypowe.

Proszę, opisz problem jeszcze raz, bez używania skrótów myślowych i nieprawidłowych określeń.

To np. w JavaScripcie to jest obiekt, nie żaden "hash":

var obj = {
  klucz: "wartosc"
};

To jest tablica (która też jest obiektem):

var arr = ["element1", "element2"];

Potrzebujesz funkcji, która będzie operowała na ... i robiła ... ?

0

Masz racje dokonałem tu pewnych uproszczeń, które prawdopodobnie wprowadzają w bład, a więc prostuje:

hashe - mam namyśli hashe znane z języków programowania server side. Czyli jak napisałeś w JavaScript to się trochę inaczej nazywa.
concat - znowu mi się pomyliło. Użyłem extend z jQuery i działa

A teraz przykład co chce zrobić:

var object1 = {
  apple: 0,
  banana: {weight: 52, price: 100},
  cherry: 97
};
var object2 = {
  banana: {price: 200},
  durian: 100
};

//tutaj chcę końcowe wartości hash mapy czyli stringi zamienić na jakiś konkretny napis np 'unknown', tak żeby po scaleniu elementy brakujące w jednej tablicy były łatwo widoczne

/* merge object2 into object1 */
$.extend(object1, object2);
0

mógłbyś napisać jak ma wyglądać ten finalny obiekt? bo nie za bardzo potrafię Cię zrozumieć :|

0
var object1 = {
  apple: 0,
  banana: {weight: 52, price: 100},
  cherry: 97,
  durian: 17
};
var object2 = {
  banana: {price: 200},
  durian: 100
};

//zamiana wartosci w ten sposob ze otrzyma sie:
//object1 == { apple: 'UNKNOWN', banana: {weight: 'UNKNOWN', price: 'UNKNOWN'}, cherry: 'UNKNOWN', durian: 'UNKNOWN'};

/* merge object2 into object1 */
$.extend(object1, object2);

//wynik jest taki:
//{ apple: 'UNKNOWN', banana: {weight: 'UNKNOWN', price: 200}, cherry: 'UNKNOWN', durian: 100};

Teraz rozumiesz ?

0
wafcio napisał(a)

hashe - mam namyśli hashe znane z języków programowania server side

"Hash" to nie jest stricte poprawne określenie również na to, co jest po stronie serwera. "Hash" to wartość zwrócona przez funkcję mieszającą (funkcję hashującą). Hash ma w miarę możliwości jednoznacznie identyfikować jakiś obiekt. Z kolei funkcja hashująca wykorzystywana jest w hashmapach. I Tobie chodzi o hashmapy. W JavaScripcie za hashmapę mogą (w sporej części) robić zwykłe obiekty. Po stronie serwera, np. w Javie EE, możemy korzystać z czegoś, co explicite nazywa się HashMapą; w innych językach hashmapy mogą być konstrukcjami samego języka podobnie jak to jest w JavaScripcie. W żadnym wypadku jednak "hash" nie jest tym samym co "hashmapa".

To tak na marginesie. Chciałem to uściślić bo -- jak widzisz -- nieścisłości mogą wybitnie utrudnić zrozumienie. Gdy masz na myśli A, ale mówisz B, nie dziw się, że ktoś rozumie B.

Co do Twojego problemu, to JavaScript nie zawiera wbudowanych funkcji, które mogłyby Ci tutaj wybitnie pomóc. Gdyby nie rekursja, można by użyć dziedziczenia prototypowego i w prototypie ustawić własności na 'Unknown'. Tutaj byłoby to trochę niepraktyczne.

Prostą, rekursywną, dwuargumentową funkcję extend można napisać na pałę (tj. bez specjalnych zabezpieczeń) od zera w kilku liniach, więc nie jest to takie trudne.

@unikalna_nazwa:
To jest jasne, ale hash to nie to samo co hashmapa, co opisałem wyżej [edit: no dobra, trochę się czepiam; faktycznie niektórzy mówią sobie skrótowo -- choć ściśle mówiąc niepoprawnie -- 'hash', gdy mają na myśli obiekt-kontener]. Obiekty JS można traktować mniej-więcej jako hashmapy. Choć nie w 100%: naturalne sprawdzanie kluczy (gdy umożliwiamy zapis dowolnych kluczy) nie jest w pełni bezpieczne w JS. No bo co, jeśli kluczem będzie hasOwnProperty? Zrobiło się to niesławne, gdy na serwerach NodeJS zaczęły wyłazić błędy i luki bezpieczeństwa. Na szczęście, można to prosto obejść.

0

to co chcesz zrobić jest... głupie i generowałoby mnóstwo redundantnych danych
czemu po prostu w funkcji która będzie sprawdzać te dane, zamiast sprawdzać czy pole = "UNKNOWN" nie sprawdzisz po prostu czy nie jest === undefined? a jeśli ta funkcja sama nie wie czego potrzebuje to coś jest nie tak
może wytłumacz lepiej po co Ci to a postaramy się wymyślić jakieś inne rozwiązanie

co do ewentualnego rozwiązania to nie wymyśliłem niczego prostszego od zwykłej rekurencji

0

Chodzi mi o to, że mam kilka hashmap z tłumaczeniami, tzn. każda hashmapa zawiera tłumaczenia obiektów w innych językach. I teraz chcę, żeby po scaleniu tych hashmap wiedzieć, które elementy nie są przetłumaczone. Chce to robić po stronie klienta, ponieważ:
a) wygenerowanie drzewa nie zuzywa zasobów serwera, tylko zasoby klienta,
b) nie wpływa na wydłużenie czasu generowania strony, tylko drzewo tłumaczeń pojawia się trochę później
c) istnieją odpowiednie biblioteki np. jsTree, który ładnie wyświetla drzewo (mechanizm przeksztalcajacy hashmape tłumaczeń do hashmapy wymaganej przez jsTree mam już opracowny)

1 użytkowników online, w tym zalogowanych: 0, gości: 1