Porównywanie wartości na dwóch listach różnej długości.

0

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.

0

Jaki jest "wyższy cel"?
Dlaczego musisz w ten sposób porównywać elementy?

0

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.

0

https://en.wikipedia.org/wiki/XY_problem

Raz jeszcze: co próbujesz osiągnąć tym, co wymyśliłeś?

0

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.

0

Chcę stworzyć z dwóch tablic jedną ale taką która nie będzie zawierała powtórzeń.

0

Tak, to rozumiem: ale w jakim celu chcesz stworzyć tę tablicę?

0

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.

1

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);
	}
});
1
const joinWithoutDuplicates = (arr1, arr2) => Array.from(new Set([...arr1, ...arr2]))
1

Polecam fajna biblioteke lodash

var one = [1, 2, 3], two=[3, 4, 5];

var myArr = _.union(one, two);
0
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.

0

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.

0

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.

1

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.

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