• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Usuwanie wielu podobnych elementów z tablicy.

Object Storage Arubacloud
0 głosów
370 wizyt
pytanie zadane 12 listopada 2022 w JavaScript przez xTMx3 Obywatel (1,560 p.)

Witam,

wczoraj pytałem o pomoc z pewnym zadaniem, dzisiaj zmagam się z kolejnym i o ile początek napisałem już sam, tak mam pewien problem z dalszą częścią przez co ponownie potrzebuję nakierowania na rozwiązanie / podpowiedzi / bądź wytłumaczenia co i jak. 

Zadanie dotyczy napisania funkcji, która przyjmuje 2 obiekty jako argumenty. Ma ona zwracać tablicę z nazwami własności obu obiektów, ale z wyłączeniem tych własności, które znajdują się w obu obiektach. Funkcja nie musi sprawdzać zagnieżdżonych obiektów, a wynikowa tablica powinna najpierw zawierać własności z pierwszego obiektu i dopiero po nich własności z drugiego. Ponadto, kolejność tych własności powinna zostać zachowana.

Np. podając jako argumenty funkcji: {x: 1, y: 1, z: 1}, {w: 2, x: 2, z: 2} zwracany wynik powinien wynosić: ['y','w']

Zrobić to chciałem jakoś tak, żeby funkcja pobierała wszystkie nazwy własności z obu obiektów i zapisywała je w jednej tablicy. Potem zostałoby już tylko usunąć elementy, których jest więcej niż jeden. Samo "pobranie" nazw własności i umieszczenie ich w tablicy napisałem tak:

var arr = Object.keys(a).concat( Object.keys(b) );

Problem mam jednak w tym, że nie wiem w jaki sposób usunąć te powtarzające się elementy jednocześnie zachowując taki porządek jak opisano w poleceniu (przez co wykluczyłem raczej użycie opcji sort). Próbowałem pisać jakieś pętle z użyciem .splice, .slice i kombinowałem z .filter, ale ciągle nie wychodziło i jako wynik otrzymywałem zupełnie inne rzeczy niż chciałem. 

Byłby ktoś w stanie podpowiedzieć jak usunąć te powtarzające się elementy?

Z góry dziękuję za wszelkie odpowiedzi. 

komentarz 13 listopada 2022 przez VBService Ekspert (253,340 p.)

2 odpowiedzi

+3 głosów
odpowiedź 12 listopada 2022 przez Wiciorny Ekspert (270,150 p.)
wybrane 13 listopada 2022 przez xTMx3
 
Najlepsza

A czy do tego nie chodzi Ci o różnice symetryczną zbiorów? Czyli elementy które nie należa do zbiorów jednoczesnie
 

function diff(first, second) {
    return [
        ...first.filter(x => !second.includes(x)),
        ...second.filter(x => !first.includes(x))
    ];
}
 
const first = [ 1, 2, 3, 4, 5 ];
const second = [ 4, 5, 6 ];
 
const difference = diff(first, second);
console.log(difference);
 
/*
    Output: [ 1, 2, 3, 6 ]
*/

 

1
komentarz 12 listopada 2022 przez TOWaD Mądrala (5,700 p.)
edycja 13 listopada 2022 przez TOWaD

Mdn devto stack

Edit: Do symetrycznej różnicy pasowały by takie wyszukania z Google :)

1
komentarz 13 listopada 2022 przez xTMx3 Obywatel (1,560 p.)
Tak, dokładnie o to chodziło. Nie wiedziałem nawet, że tak się to nazywa szczerze powiedziawszy, a polecenie zadania nic takiego nie mówiło przez co nawet przez myśl taka opcja mi nie przeszła. Bardzo dziękuję wam za pomoc.
1
komentarz 13 listopada 2022 przez VBService Ekspert (253,340 p.)

Podrasowałbym nieco np.

const difference = (a, b) => a.filter(v => !b.includes(v))

const symmetricDifference = (first, ...rest) => 
  [ ...new Set(rest.reduce(
    (a, b) => [ ...difference(a, b), ...difference(b, a) ], first
  ))]

// [1,'Lorem']
console.log(symmetricDifference([1, 'ipsum', 'ipsum'], ['Lorem', 'ipsum']));
// [1,3,5,6]
console.log(symmetricDifference([1, 2, 2], [2, 3, 4], [4, 5, 5, 6]));

 

komentarz 13 listopada 2022 przez Wiciorny Ekspert (270,150 p.)
edycja 13 listopada 2022 przez Wiciorny
fajnie wygląda, ale zwiększyłeś liczbę operacji o co najmniej o(n)

*Uzasadniam to faktem niestety tego, albo stety bo to jednak czasami zaleta: strumienie są leniwe, a dodatkowo set będzie musiał przetworzyć wszystkie elementy raz jesczcze zanim zwróci wynik na którym jeszcze robisz operacje spread. Wrzuć sobie to do datadog- dla js, albo profiler'a o ile jest w js.
1
komentarz 13 listopada 2022 przez VBService Ekspert (253,340 p.)

Chodziło Mi w kontekście załączonych przykładów.

[1, 'ipsum', 'ipsum'], ['Lorem', 'ipsum']
[1, 2, 2], [2, 3, 4], [4, 5, 5, 6]

IMO powinno się wybrać wersję dopasowaną max. do kontekstu. smiley

Twoja wersja jest w porządku. 

+2 głosów
odpowiedź 12 listopada 2022 przez ScriptyChris Mędrzec (190,190 p.)

Możesz użyć metody filter na obu tablicach, gdzie zwrócisz te wartości z jednej tablicy, które nie znajdują się w drugiej.

Zakładając, że wyciągniesz klucze z dwóch obiektów dostarczonych w parametrach do tablic nazwanych odpowiednio left i right:

  • dla każdej wartości w tablicy left sprawdź, czy nie znajduje się ona w tablicy right
  • dla każdej wartości w tablicy right sprawdź, czy nie znajduje się ona w tablicy left

Metoda filter zwróci tablice, których wartości nie znajdują się w "tej drugiej" porównywanej tablicy.

komentarz 12 listopada 2022 przez xTMx3 Obywatel (1,560 p.)

Rozumiem twój zamysł, ale z wykonaniem mam problem. Próbowałem zrobić to tak (póki co, dla tego pierwszego argumentu) : 

function funkcjaObiekty(a, b){
  var arA = Object.keys(a);
  var arB = Object.keys(b);
  var resA,resB;
  for(let i=0;i<=arA.length-1;i++){
    resA = arA.filter(arA => arA.includes(arB[i]));
  }
  return resA;
}

Ale chyba nie do końca o to chodziło, bo nie działa jak należy no i ponadto czytając to, sam widzę, że chyba coś jest nie tak. 

Mógłbym prosić o wytłumaczenie jak dokładnie to porównywanie miałoby wyglądać? Ma to być jakoś w pętli robione, czy może same metody filter i includes są wystarczające? 

1
komentarz 12 listopada 2022 przez ScriptyChris Mędrzec (190,190 p.)
resA = arA.filter(arA => arA.includes(arB[i]));

Ten fragment kodu przenieś poza pętlę (jest ona niepotrzebna), zastosuj negację przy wołaniu includes i zrób analogicznie dla drugiej tablicy.

1
komentarz 12 listopada 2022 przez Wiciorny Ekspert (270,150 p.)

Różnicą symetryczna zbiorów nie będzie wynikiem może? 
.

Metoda filter zwróci tablice, których wartości nie znajdują się w "tej drugiej" porównywanej tablicy

 

 

komentarz 13 listopada 2022 przez xTMx3 Obywatel (1,560 p.)
Powyżej ktoś podał inne rozwiązanie, które zadziałało, ale mimo to, spróbuję jeszcze w ten sposób się trochę pobawić, bo wczoraj nie wychodziło jak trzeba.

Dziękuję mimo wszystko za podpowiedzi i pomoc.
komentarz 13 listopada 2022 przez ScriptyChris Mędrzec (190,190 p.)

Powyżej ktoś podał inne rozwiązanie

Rozwiązanie jest to samo - filter oraz zanegowany includes - tyle, że podane w formie gotowca. Ja próbowałem Cię naprowadzić krok po kroku. 

Podobne pytania

+1 głos
2 odpowiedzi 371 wizyt
0 głosów
4 odpowiedzi 3,118 wizyt
+1 głos
1 odpowiedź 164 wizyt
pytanie zadane 30 kwietnia 2018 w JavaScript przez GracjanDogg Użytkownik (840 p.)

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...