0

What I'm doing wrong when I try to get some objects into an array of objects based in another array of objects (that is result of selection of user):

//Original array
let obj1 = [
    {"Nome": "João", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Pedro", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Marcos", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Lucas", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Tiago", "Idade": 16, "Fone 1": "55 5555"}
];
//Array selected by the user to delete:
let obj2 = [
    {"Nome": "Marcos", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Lucas", "Idade": 16, "Fone 1": "55 5555"},
];

function deleteObj(val1, val2){
    let val = [];
    for (const i of val1) {
        for (const x of val2) {
            JSON.stringify(i) !== JSON.stringify(x) ? val.push(i) : {};
        }
    }
    return val;
}
console.log(deleteObj(obj1, obj2));

I'll use this code to remove the values selected by the user in the JSON file, but, when I run the result is:

[
  { Nome: 'João', Idade: 16, 'Fone 1': '55 5555' },
  { Nome: 'João', Idade: 16, 'Fone 1': '55 5555' },
  { Nome: 'Pedro', Idade: 16, 'Fone 1': '55 5555' },
  { Nome: 'Pedro', Idade: 16, 'Fone 1': '55 5555' },
  { Nome: 'Marcos', Idade: 16, 'Fone 1': '55 5555' },
  { Nome: 'Lucas', Idade: 16, 'Fone 1': '55 5555' },
  { Nome: 'Tiago', Idade: 16, 'Fone 1': '55 5555' },
  { Nome: 'Tiago', Idade: 16, 'Fone 1': '55 5555' }
]

Seems that the "non-selected" values are added too.

Jorge
  • 3
  • 3
  • Does this answer your question? [How to get the difference between two arrays in JavaScript?](https://stackoverflow.com/questions/1187518/how-to-get-the-difference-between-two-arrays-in-javascript) – Diego D Sep 26 '22 at 14:11
  • your strategy to find the difference between two arrays is very wrong by the way. – Diego D Sep 26 '22 at 14:11
  • use `.filter` to filter an array. Also, don't compare 2 objects by stringifying them. That's horribly unreliable and slow. Compare values. – Cerbrus Sep 26 '22 at 14:12
  • 1
    You are basically creating a "cross product" here, you are making 5 times 2 comparisons, so ten in total. So `{"Nome": "Lucas", "Idade": 16, "Fone 1": "55 5555"}` does not only get compared to `{"Nome": "Lucas", "Idade": 16, "Fone 1": "55 5555"}` , it also gets compared to `{"Nome": "Marcos", "Idade": 16, "Fone 1": "55 5555"}`. It only equals the first one, but not the second one - so you are putting it into your result array one time. Which is wrong, it should be left out altogether. – CBroe Sep 26 '22 at 14:16
  • 1
    I double-checked, "difference" is the correct word in set theory. My bad, @DiegoD. – Cerbrus Sep 26 '22 at 14:35

1 Answers1

2

.filter the first array, by checking if the second array contains objects with the same Nome.

//Original array
let obj1 = [
    {"Nome": "João", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Pedro", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Marcos", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Lucas", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Tiago", "Idade": 16, "Fone 1": "55 5555"}
];
//Array selected by the user to delete:
let obj2 = [
    {"Nome": "Marcos", "Idade": 16, "Fone 1": "55 5555"},
    {"Nome": "Lucas", "Idade": 16, "Fone 1": "55 5555"},
];

function deleteObj(val1, val2){
  return val1.filter(
    row => !val2.some(toRemove => row.Nome === toRemove.Nome)
  );
}

console.log(deleteObj(obj1, obj2));

If necessary, you can add extra fields to the equality check:

return val1.filter(
  row => !val2.some(toRemove =>
    row.Nome === toRemove.Nome &&
    row.Idade === toRemove.Idade &&
    row['Fone 1'] === toRemove['Fone 1'])
);
Cerbrus
  • 70,800
  • 18
  • 132
  • 147