Cześć,
Mam problem i chciałbym Was prosić o pomoc jak w ogóle koncepcyjnie go rozwiązać bo ja chyba wymiękam :(. Posiadam dwie listy o różnej długości. Nazwijmy jedną listę: Lista_A zaś drugą: Lista_B. Teraz muszę zrobić coś takiego że porównuję obie listy ze sobą i jeżeli jakiś element z listy B istnieje już na liście A (oczywiście mam parametr po którym je porównuję) to idę dalej natomiast jeżeli jakiś element z listy B nie istnieje na liście A to muszę zrobić push'a i go tam dodać. Myślałem już nawet aby użyć do tego celu jakiejś listy pomocniczej i na początku tylko porównać, jak istnieje to olać jak nie istnieje to dodać do listy pomocniczej a później tylko po tej liście pomocniczej przeiterować i dodać wszystkie elementy z niej do list A. Tylko brakuje mi pomysłu na warunek bo robię pętlę w pętli i co dalej? Sprawdzam w tej najgłębszej pętli że i-ty element z listy A jest równy j-emu elementowi z listy B jak jest równy to co, przerywam sprawdzanie? Jak je przerwę ro nie sprawdzę kolejnych elementów. A z kolej jak dam warunek czy i-ty element z listy A jest różny od j-ego elementu listy b i go dodać do listy pomocniczej to wcale nie oznacza że np j-ty element z listy b nie będzie równy i-temu + 1 elementowi z listy A, a wówczas nie powinienem takiego elementu dodawać no i trochę sam się zapętliłem :(. Proszę Was o pomoc.
Jaki jest "wyższy cel"?
Dlaczego musisz w ten sposób porównywać elementy?
To znaczy sposób może być dowolny. Ja nie mówię że musi być konkretnie ten. Liczy się efekt jaki mam uzyskać a mianowicie żeby dodać elementy z Listy B do Listy A ale tylko wtedy gdy dany element z Listy B nie istnieje już w liście A (sprawdzenie obywa się po konkretnej wartości). Bo jak dodaję je bez sprawdzania to efekt mam taki że lista A ma powtarzające się wartości a to jest błędem. Myślałem nawet żeby zrobić odwrotnie czyli na początku przeiterować i jak jakiś element z listy B istnieje na liście A to go usunąć a później zawartość całej listy B dodać do A, wówczas otrzymuję zamierzony efekt ale nie jest to do końca eleganckie rozwiązanie.
https://en.wikipedia.org/wiki/XY_problem
Raz jeszcze: co próbujesz osiągnąć tym, co wymyśliłeś?
Jeszcze też myślałem o tym aby połączyć obie tablice w jedną a następnie usunąć z niej duplikaty ale też nie wiem czy jest to poprawne rozwiązanie.
Chcę stworzyć z dwóch tablic jedną ale taką która nie będzie zawierała powtórzeń.
Tak, to rozumiem: ale w jakim celu chcesz stworzyć tę tablicę?
Ale to jest konieczne do rozwiązania tego problemu? Po prostu chcę stworzyć z dwóch listy jedną i wyświetlić ją użytkownikowi bez powtarzających się elementów ale nie wiem czy cel takiego zabiegu ma jakiekolwiek znaczenie w sposobie jego rozwiązania.
Nie przeczytałeś zalinkowanego przeze mnie artykułu do problemu XY, prawda? :-)
Tak czy siak - chodzi o coś takiego?
itemsB.forEach((item) => {
if (!itemsA.includes(item)) {
itemsA.push(item);
}
});
const joinWithoutDuplicates = (arr1, arr2) => Array.from(new Set([...arr1, ...arr2]))
Polecam fajna biblioteke lodash
var one = [1, 2, 3], two=[3, 4, 5];
var myArr = _.union(one, two);
Patryk27 napisał(a):
Nie przeczytałeś zalinkowanego przeze mnie artykułu do problemu XY, prawda? :-)
Tak czy siak - chodzi o coś takiego?
itemsB.forEach((item) => { if (!itemsA.includes(item)) { itemsA.push(item); } });
Chyba jednak nie do końca działa. Zrobiłem sobie prosty przykład w konsoli na dwóch tablicach z owocami:
var fruitsA = [{
name: "banana"
}, {
name: "apple"
}, {
name: "orange"
}, {
name: "kiwi"
}]
var fruitsB = [{
name: "banana"
}, {
name: "apple"
}, {
name: "orange"
}, {
name: "kiwi"
}, {
name: "lemon"
}, {
name: "struwbery"
}]
fruitsB.forEach(function(item) {
if (!fruitsA.includes(item)) {
fruitsA.push(item);
}
});
fruitsA;
I za otrzymuję tablicę 10 elementową z powtórzeniami a powinno być tych elementów 6.
No bo jak Cię @Patryk27 pyta o konkret to nie podajesz, a to jakie dane i po co chcesz przetwarzać jest kluczowe do rozwiązania problemu. Przykłady nie działają, bo Ty potrzebujesz porówywania wartości obieków, a JS domyślnie porównuje referencje.
Właśnie teraz też do tego doszedłem. Jak te listy przekształcę na listy typu prostego i trzymam w nich same wartości to jest ok. Natomiast w takim przypadku gdy mam listy obiektów już nie działa. W takim razie się nie zrozumieliśmy ponieważ ja to pytanie Patryka odebrałem tak jakby mnie pytał do czego będę tego używał, nie wiedziałem że chodzi o to, co trzymam w tych listach ale jest to mój błąd ponieważ powinienem napisać to na początku że jest to lista obiektów.
Ogólnie to nie będę tu implementował rozwiązania na tablicach, bo imo nie ma sensu (patrz drugi przykład) - ale skoro już @shagrin wspomniała o Lodashu to łap przykład by było z czym porównywać moje rozwiązanie:
const a = [
{ name: 'foo', other: 1 },
{ name: 'bar', other: 1 },
{ name: 'baz', other: 1 },
]
const b = [
{ name: 'bar', other: 1 },
{ name: 'baz', other: 1 },
{ name: 'bat', other: 1 },
]
const unique = _.unionBy(a, b, 'name')
console.log(unique)
CodePen: https://codepen.io/anon/pen/aGJbXo?editors=0012
Ale! - jeśli obiekty można jednoznacznie zidentyfikować po jednym polu, jakimś ID cz name
w Twoim przypadku, to używanie tablicy jest niewydajne i niewygodne - lepiej zrobić z tego literał obiektowy, gdzie czas dostępu po kluczu jest stały:
const a = {
foo: { name: 'foo', other: 1 },
bar: { name: 'bar', other: 1 },
baz: { name: 'baz', other: 1 },
}
const b = {
bar: { name: 'bar', other: 1 },
baz: { name: 'baz', other: 1 },
bat: { name: 'bat', other: 1 },
}
const unique = { ...b, ...a }
// or:
// const unique = Object.assign({}, b, a)
console.log(unique)
CodePen: https://codepen.io/anon/pen/RypwyR?editors=0012
Wydajność drugiej wersji już w tak prostym przykładzie jest o rząd wielkości lepsza, a samo rozwiązanie jest banalne i nie wymaga pisania specjalnej funkcji / użycia biblioteki.