I've got an array of objects that look like this:
[{"Account Name":"John Hill","Account Type":"Services","Organization":"A","Account Address":"2 Westall Rd"},
{"Account Name":"John Hill","Account Type":"Training","Organization":"A","Account Address":"2 Westall Rd"},
{"Account Name":"Dave Butcher","Account Type":"Engieering","Organization":"A","Account Address":"Level 1/55 Sunshine Blvd"},
{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd},
{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd"}]
From the objects above, there's some duplicate account names, but they're unique due to the account type. I'm trying to figure out a way to filter it so that a combination of key values would make an object unique, rather than a single key. Something like filtering the Account Name
&& Account Type
.
I've also noticed some solutions would create a new array and include only the keys to filter, but I'd like the solution to preserve all keys from an object rather than creating a new object with lesser keys.
Expected result would look like this:
[{"Account Name":"John Hill","Account Type":"Services","Organization":"A","Account Address":"2 Westall Rd"},
{"Account Name":"John Hill","Account Type":"Training","Organization":"A","Account Address":"2 Westall Rd"},
{"Account Name":"Dave Butcher","Account Type":"Engieering","Organization":"A","Account Address":"Level 1/55 Sunshine Blvd"},
{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd}]
CodePudding user response:
const array = [{"Account Name":"John Hill","Account Type":"Services","Organization":"A","Account Address":"2 Westall Rd"},
{"Account Name":"John Hill","Account Type":"Training","Organization":"A","Account Address":"2 Westall Rd"},
{"Account Name":"Dave Butcher","Account Type":"Engieering","Organization":"A","Account Address":"Level 1/55 Sunshine Blvd"},
{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd"},
{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd"}]
const filteredArr = array.reduce((acc, current) => {
const x = acc.find(item => (item['Account Name'] === current['Account Name'] ) && (item['Account Type'] === current['Account Type']));
if (!x) {
return acc.concat([current]);
} else {
return acc;
}
}, []);
console.log(filteredArr);
CodePudding user response:
Use a Map
. Loop over the array and on each iteration create a key from the Account Name
and Account Type
, and set
the whole object as its value. Finally use values()
to return a deduped array.
const data=[{"Account Name":"John Hill","Account Type":"Services",Organization:"A","Account Address":"2 Westall Rd"},{"Account Name":"John Hill","Account Type":"Training",Organization:"A","Account Address":"2 Westall Rd"},{"Account Name":"Dave Butcher","Account Type":"Engieering",Organization:"A","Account Address":"Level 1/55 Sunshine Blvd"},{"Account Name":"Jake Wellington","Account Type":"Management",Organization:"A","Account Address":"11 Maroochy Rd"},{"Account Name":"Jake Wellington","Account Type":"Management",Organization:"A","Account Address":"11 Maroochy Rd"}];
const map = new Map();
for (const obj of data) {
const key = `${obj['Account Name']}-${obj['Account Type']}`;
map.set(key, obj);
}
console.log([...map.values()]);
CodePudding user response:
You can use the hash group approach to filter by several properties:
const data = [{"Account Name":"John Hill","Account Type":"Services","Organization":"A","Account Address":"2 Westall Rd"},{"Account Name":"John Hill","Account Type":"Training","Organization":"A","Account Address":"2 Westall Rd"},{"Account Name":"Dave Butcher","Account Type":"Engieering","Organization":"A","Account Address":"Level 1/55 Sunshine Blvd"},{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd"},{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd"}];
const uniqHashes = data.reduce((acc, item) => {
const hash = [item['Account Name'], item['Account Type']].join('-');
acc[hash] ??= item
return acc;
}, {});
const uniqs = Object.values(uniqHashes);
console.log(uniqs);
.as-console-wrapper { max-height: 100% !important; top: 0 }
CodePudding user response:
Use the uniqueness of the keys of the js objects
function filterDuplicates(arr){
let o ={}
arr.forEach(e => {
// check all object
//o[JSON.stringify(e)]=e;
// check only acc name and type
o[e['Account Name'] e['Account Type']]=e;
});
return Object.values(o);
}
CodePudding user response:
This solution tries to keep it simple. We collect all distinct rows into a new array and check, before adding, if a 'equivalent' row is already there. Time complexity is O(n^2)
. So probably not optimal for really large tables, where one should prefer a solution like offered by @Andy above (using composed keys and a map - that's O(n)
)
const array = [{"Account Name":"John Hill","Account Type":"Services","Organization":"A","Account Address":"2 Westall Rd"},
{"Account Name":"John Hill","Account Type":"Training","Organization":"A","Account Address":"2 Westall Rd"},
{"Account Name":"Dave Butcher","Account Type":"Engieering","Organization":"A","Account Address":"Level 1/55 Sunshine Blvd"},
{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd"},
{"Account Name":"Jake Wellington","Account Type":"Management","Organization":"A","Account Address":"11 Maroochy Rd"}]
const distinctRows = []
array.forEach((thisRow) => {
if (distinctRows.find((otherRow) => (thisRow['Account Name'] === otherRow['Account Name'] ) && (thisRow['Account Type'] === otherRow['Account Type'])) === undefined) {
distinctRows.push(thisRow);
}
})
console.log(distinctRows);