I have two arrays of objects like:
[{id: "1", name: "item1", checked: true}, {id: "2", name: "item2", checked: true}, {id: "3", name: "item3", checked: true}]
and
[{id: "1", name: "item1", checked: true}, {id: "2", name: "item2", checked: true}, {id: "3", name: "item3", checked: false}]
The first array holds the default states, the second one hold the current states. I'd like to filter out the objects that "checked" is changed. The expected result would be
[{id: "3", name: "item3", checked: false}]
I tried with loadash differentBy, but it returns empty array:
const diff=_.differenceBy(array1, array2, "checked")
Can anyone help out? Thanks.
CodePudding user response:
A very compact solution -but O(n^2)- with _.differenceWith:
const xs = [
{id: "1", name: "item1", checked: true},
{id: "2", name: "item2", checked: true},
{id: "3", name: "item3", checked: true}
]
const ys = [
{id: "1", name: "item1", checked: true},
{id: "2", name: "item2", checked: true},
{id: "3", name: "item3", checked: false}
]
const zs = _.differenceWith(xs, ys, _.isEqual)
// [{ id: "3", name: "item3", checked: true }]
A bit more verbose, but this one is O(n):
const xsById = _.keyBy(xs, x => x.id)
const zs = ys.filter(y => xsById[y.id]?.checked !== y.checked)
CodePudding user response:
You could use a method like this, if an item in the array compared by keyToCompare and identified by it's identifier (In your situation checked
and id
).
const differenceBy = (arr1, arr2, keyToCompare, identifier) => {
const diff = []
arr1.forEach(arr => {
const arr2Item = arr2.find(i => i[identifier] === arr[identifier])
if(arr[keyToCompare] !== arr2Item[keyToCompare]) {
diff.push(arr2Item)
}
})
return diff
}
Example:
const arr1 = [{id: "1", name: "item1", checked: true}, {id: "2", name: "item2", checked: true}, {id: "3", name: "item3", checked: true}]
const arr2 = [{id: "1", name: "item1", checked: true}, {id: "2", name: "item2", checked: true}, {id: "3", name: "item3", checked: false}]
const differenceBy = (arr1, arr2, keyToCompare, identifier) => {
const diff = []
arr1.forEach(arr => {
const arr2Item = arr2.find(i => i[identifier] === arr[identifier])
if(arr[keyToCompare] !== arr2Item[keyToCompare]) {
diff.push(arr2Item)
}
})
return diff
}
console.log(differenceBy(arr1, arr2, 'checked', 'id'))
CodePudding user response:
I guess you could use something like that
function compareArrays(arr1, arr2, keyCompared) {
let d = []
arr1.forEach((e,i)=>{
if(e[keyCompared] !== arr2[i][keyCompared])
d.push(e)
})
return d
}
Example:
let array1 = [{id: "1", name: "item1", checked: true}, {id: "2", name: "item2", checked: true}, {id: "3", name: "item3", checked: true}]
let array2 = [{id: "1", name: "item1", checked: true}, {id: "2", name: "item2", checked: true}, {id: "3", name: "item3", checked: false}]
function compareArrays(arr1, arr2, keyCompared) {
let d = []
arr1.forEach((e,i)=>{
if(e[keyCompared] !== arr2[i][keyCompared])
d.push(e)
})
return d
}
console.log(compareArrays(array1,array2,'checked'))