简体   繁体   中英

Javascript loop trough array of object and return one object containing only keys that have their values changed

I have an array of objects I need to loop through and check if the key of the object has different value. If so return this key.

const arrayOfObjects = [
  { item: { first_name: "Joe", last_name: "Dow", age: 15 } },
  { item: { first_name: "Joe", last_name: "d", age: 15 } },
  { item: { first_name: "Joe", last_name: "Dow", age: 20 } }
];

expected result should be

const result = {
  last_name: true,
  age: true
}

PS: each object has always the same number of keys

You can loop through the arrayOfObjects . Check if current item 's keys have different value compared to previous object's item . If yes, set that key to true in result

 const arrayOfObjects = [{ item: { first_name: "Joe", last_name: "Dow", age: 15 } }, { item: { first_name: "Joe", last_name: "d", age: 15 } }, { item: { first_name: "Joe", last_name: "Dow", age: 20 } }]; const result = {}; arrayOfObjects.forEach(({ item }, i, arr) => { if (i === 0) return; // skip the first item const prev = arr[i - 1].item; // get the previous item for (const key in item) { if (item[key] !== prev[key]) result[key] = true } }) console.log(result) 

Just use find . It's more clear

 const data = [ { item: { first_name: "Joe", last_name: "Dow", age: 15 } }, { item: { first_name: "Joe", last_name: "d", age: 15 } }, { item: { first_name: "Joe", last_name: "Dow", age: 20 } } ]; let result = {}; for (var key in data[0].item) { if (data.find((el) => el.item[key] !== data[0].item[key])) { result[key] = true; } } console.log(result); 

You could take a check which looks into the nested object.

 function check(source, target, result) { Object.entries(source).forEach(([k, v]) => { if (v && typeof v === 'object') return check(v, target[k], result); if (result[k] === undefined) result[k] = true; result[k] = result[k] && v === target[k]; }); return result; } var arrayOfObjects = [{ item: { first_name: "Joe", last_name: "Dow", age: 15 } }, { item: { first_name: "Joe", last_name: "d", age: 15 } }, { item: { first_name: "Joe", last_name: "Dow", age: 20 } }], result = arrayOfObjects.reduce((r, o, _, [q]) => check(q, o, r), {}); console.log(result); 

Here's a solution which keeps a flag for uniqueness, filters out any unique items, maps them to your desired format and creates an object of the resulting entries. Time complexity: O(n * length_of_item_with_most_keys), space complexity: O(n).

 const arrayOfObjects = [ { item: { first_name: "Joe", last_name: "Dow", age: 15 } }, { item: { first_name: "Joe", last_name: "d", age: 15 } }, { item: { first_name: "Joe", last_name: "Dow", age: 20 } } ]; const result = Object.fromEntries( Object.entries(arrayOfObjects.reduce((a, e) => { for (const k in e.item) { if (!a[k]) { a[k] = {val: e.item[k], unique: true}; } else if (a[k].unique) { a[k].unique = a[k].val === e.item[k]; } } return a; }, {}) ).filter(e => !e[1].unique).map(e => [e[0], true])); console.log(result); 

You can also solve this with Array.reduce and Set where you would group on the key and keep adding the values. Then filter on the size of the set ... if larger than 1 you had more than one value:

 const data = [ { item: { first_name: "Joe", last_name: "Dow", age: 15 } }, { item: { first_name: "Joe", last_name: "d", age: 15 } }, { item: { first_name: "Joe", last_name: "Dow", age: 20 } } ]; let result = data.reduce((r,{item},i,a) => { Object.keys(item).forEach(k => r[k] = (r[k] || new Set()).add(item[k])) return i == (a.length-1) ? Object.keys(r).filter(k => r[k].size > 1).reduce((r,k) => (r[k] = true, r), {}) : r }, {}) console.log(result) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM