1

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.

3 Answers 3

1

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)
Sign up to request clarification or add additional context in comments.

Comments

1

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'))

Comments

0

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'))

1 Comment

Thanks for your quick response. It does not seem working if the orders of the objects are not the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.