Array’s – Reducing all duplicates
Years ago when I blogged regularly about Actionscript/Flex some of the most simple and yet popular posts were on array’s.
Today I find myself doing something similar in Javascript – and there is no out of the box solution that I’m aware off.
Take a large array (where duplicates probably exist) and condense it into a collection of unique items.
Let’s say your hitting some API and it returns 1000’s of results, and in that result you want to find out how many unique types of XXXX there are. How would you do that?
One simple way is to use an object and store the items using the key part of an object.
const duplicatedArray = [ { name: "Bob", hairColour: "Black" }, { name: "Jane", hairColour: "Grey" }, { name: "Mark", hairColour: "Red" }, { name: "Marsalli", hairColour: "Black" }, { name: "Rachel", hairColour: "Brown" }, { name: "Craig", hairColour: "Red" }, ]; const getUniqueCollection = (keyFilter) => { const reduced = {}; duplicatedArray.forEach((person) => { reduced[person[keyFilter]] = person[keyFilter]; }); return reduced; };
What’s going on is that it will pass only once through the array with duplication’s, and each time it will write that to the reduced
object. If, as there is in this example it comes across two Black
hair types then the 2nd one will overwrite the first, therefor removing any duplication.
End result, you now have an Object (some may well call this a dictionary) that on inspection contains unique list of hair colours. This for example could be used to populate a dropdown box or similar. Or you could use the below to iterate over the new object.
for (var key in uniqueCollection) { var value = uniqueCollection[key]; // do something... }
Lets say you’ve a more complex object!
const complexDuplicatedArray = [ { brand: "Ford", colour: "Black", ignoredProperty: "XXX" }, { brand: "Tesla", colour: "Grey", ignoredProperty: "AAA" }, { brand: "VW", colour: "Red", ignoredProperty: "222" }, { brand: "Ford", colour: "Black", ignoredProperty: "111" }, { brand: "Tesla", colour: "Brown", ignoredProperty: "ZZZ" }, { brand: "VW", colour: "Red", ignoredProperty: "YYY" }, ]; // pass in ["brand", "colour"] as the parameter keyFilter const getComplexUniqueCollection = (keyFilter) => { const reduced = {}; complexDuplicatedArray.forEach((car) => { const keyValue = JSON.stringify(car, keyFilter); reduced[keyValue] = keyValue; }); return reduced; };
So here we are filtering on 2 keys, the brand and the colour. Convert the object to a string and drop the properties that we do not care about.
JSON.stringify
The stringify part in the above is key. What’s it’s doing is taking an array of strings to include in the stringify process.
So usingmyObj = { brand: "Ford", colour: "Black", ignoredProperty: "XXX" }
JSON.stringify( myObj, [‘brand’, ‘colour’]); will output"{"brand":"Ford","colour":"Black"}"
This is ideal for using as the key to store, so if there is another Ford
car that is Black
with a different property that you wish to ignore, then it’s not included.