• 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.

Cloud VPS
0 głosów
634 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 (256,600 p.)

2 odpowiedzi

+3 głosów
odpowiedź 12 listopada 2022 przez Wiciorny Ekspert (281,450 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 (6,480 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 (256,600 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 (281,450 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 (256,600 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 (281,450 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 636 wizyt
0 głosów
4 odpowiedzi 3,940 wizyt
+1 głos
1 odpowiedź 221 wizyt
pytanie zadane 30 kwietnia 2018 w JavaScript przez GracjanDogg Użytkownik (840 p.)

93,457 zapytań

142,452 odpowiedzi

322,722 komentarzy

62,837 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

Kursy INF.02 i INF.03
...