iwato 18 Report post Posted June 7 (edited) BACKGROUND: I recently discovered the following piece of code on StackOverflow,. Although it works for a single property comparison, I do not understand it well enough to expand it to cope with multiple properties. function getUnique(inputArr, comp) { const unique = inputArr.map(e => e[comp]).map((e, i, final) => final.indexOf(e) === i && i).filter(e => inputArr[e]).map(e => inputArr[e]); return unique; } I would like to create a function that would permit the comparison of multiple values on the order of function getUnique(inputArr, comp1 [, comp2[, comp3 [...]]]){...} Any suggestions? At minimum could you help with a better understanding of how it does what it does. It maps and filters, but in a manner that I do not comprehend easily enough to manipulate. Roddy PS. A little experimentation came up with the following solution. function getUnique(inputArr, comp1, comp2) { const unique = inputArr.map(e => e[comp1] && e[comp2]) .map((e, i, final) => final.indexOf(e) === i && i) .filter(e => inputArr[e]) .map(e => inputArr[e]); return unique; } It achieves my goal, but a little more understanding is still requested. Edited June 7 by iwato Solution Provided Quote Share this post Link to post Share on other sites
justsomeguy 1,134 Report post Posted June 7 Here's a version if you're not into the whole brevity thing: function getUnique(inputArr, comp) { const unique = inputArr.map(function (e) { // return an array of only one property from the original array of objects (if defined) console.log(e[comp]); return e[comp]; }).map(function (e, i, final) { console.log("final", final); console.log("e", e); console.log("i", i); // return an array of either false values or indexes // this will result in an array where each value is listed only once, in the first position it appears, // and any other appearances will be false // the array will be the same length return final.indexOf(e) === i && i; }).filter(function (e) { console.log("e", e); console.log(inputArr[e]); // this will create an array of objects from the original array in each index from the previously mapped temp array // this will exclude the duplicates because those indexes in the previous array are set to false return inputArr[e]; }).map(function (e) { console.log("e", e); console.log(inputArr[e]); // this will reindex the array to remove "holes" return inputArr[e]; }); console.log(unique); return unique; } var ar = [ { 'prop': 1 }, { 'prop': 2 }, { 'prop': 1 }, { 'prop': 3 }, { 'prop': 1 }, { 'prop': 4 }, { 'prop2': 1 }, { 'prop3': 1 } ]; getUnique(ar, 'prop'); I would like to create a function that would permit the comparison of multiple values on the order of What's the purpose? This function takes an array of objects, and will return an array of those objects that have unique values for a particular property. How do multiple values fit into that? Do you have an example? 1 Quote Share this post Link to post Share on other sites
iwato 18 Report post Posted June 7 I have erred. What worked for objects with three properties does not work for objects with two properties. I had hoped that my modification would have rendered the following transformation, but it does not. Input Array Object { visitorID: "6b77f74d969f0254", fullDate: "2019/01/01" } Object { visitorID: "6b77f74d969f0254", fullDate: "2019/01/01" } Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" } Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" } Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" } Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" } Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/04" } Object { visitorID: "470b11ecb96f51a8", fullDate: "2019/01/04" } Object { visitorID: "470b11ecb96f51a8", fullDate: "2019/01/05" } Object { visitorID: "7783172ce39cd663", fullDate: "2019/01/05" } Output Array Object { visitorID: "6b77f74d969f0254", fullDate: "2019/01/01" } Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/03" } Object { visitorID: "8305d1d7c98cfe07", fullDate: "2019/01/04" } Object { visitorID: "470b11ecb96f51a8", fullDate: "2019/01/04" } Object { visitorID: "470b11ecb96f51a8", fullDate: "2019/01/05" } Object { visitorID: "7783172ce39cd663", fullDate: "2019/01/05" } I expected the above transformation base on the below transformation var dataArr = [ {"name":"Steven Smith","country":"England","age":35}, {"name":"Hannah Reed","country":"Scottland","age":23}, {"name":"Steven Smith","country":"England","age":35}, {"name":"Robert Landley","country":"England","age":84}, {"name":"Steven Smith","country":"England","age":35}, {"name":"Robert Landley","country":"England","age":56} ]; var output = [ {"name":"Steven Smith","country":"England","age":35}, {"name":"Hannah Reed","country":"Scottland","age":23}, {"name":"Robert Landley","country":"England","age":84}, {"name":"Robert Landley","country":"England","age":56} ]; In both cases I used two variables for comparison. In the first case, however, there were only two variables to compare. In the second there was a third variable for which no matching was intended. Alas, where have I gone wrong? Roddy Quote Share this post Link to post Share on other sites
iwato 18 Report post Posted June 7 Thank you, SVG, for your explanation of the one property-value pair reduction. My transformation of the one property-value pair reduction into a dual property-value pair reduction works for objects with three properties, but not two. Can you explain why? Roddy Quote Share this post Link to post Share on other sites
justsomeguy 1,134 Report post Posted June 7 Are you referring to code that was edited into your first post? Quote Share this post Link to post Share on other sites
justsomeguy 1,134 Report post Posted June 7 Add output statements similar to what I have, you should see why it's not comparing things the way you expect. Quote Share this post Link to post Share on other sites
iwato 18 Report post Posted June 8 The Data var visitData = [ {'visitorID':'6b77f74d969f0254','fullDate':'2019/01/01'}, {'visitorID':'6b77f74d969f0254','fullDate':'2019/01/01'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/04'}, {'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/04'}, {'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/05'}, {'visitorID':'7783172ce39cd663','fullDate':'2019/01/05'}, {'visitorID':'1834494d8537012d','fullDate':'2019/01/06'}, {'visitorID':'3321037b66164959','fullDate':'2019/01/06'} ]; Alright, I have played with the map function and discovered that the following code displays exactly what I want -- a subset of unique objects. Simply I do not know how to convert it into anything useful. The Code function getUniqAnalysis(inputArr, comp1, comp2) { const unique = inputArr.map(function(e) { console.log('e[comp1]: ' + e[comp1] + ' e[comp2]: ' + e[comp2]); }); } Something Useful var somethingUseful = [ {'visitorID':'6b77f74d969f0254','fullDate':'2019/01/01'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/04'}, {'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/04'}, {'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/05'}, {'visitorID':'7783172ce39cd663','fullDate':'2019/01/05'}, {'visitorID':'1834494d8537012d','fullDate':'2019/01/06'}, {'visitorID':'3321037b66164959','fullDate':'2019/01/06'} ]; Please advise. Roddy Quote Share this post Link to post Share on other sites
JMRKER 7 Report post Posted June 9 This seemed to me to be an easier solution to your problem. Check the reference links for further information or look up the new Set() function of ES6 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width-device-width,initial-scale=1.0, user-scalable=yes"/> <title> Unique Object Entries </title> <!-- From: http://w3schools.invisionzone.com/topic/59291-eliminating-objects-of-an-array/ --> </head> <body> <script> var visitData = [ {'visitorID':'6b77f74d969f0254','fullDate':'2019/01/01'}, {'visitorID':'6b77f74d969f0254','fullDate':'2019/01/01'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/03'}, {'visitorID':'8305d1d7c98cfe07','fullDate':'2019/01/04'}, {'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/04'}, {'visitorID':'470b11ecb96f51a8','fullDate':'2019/01/05'}, {'visitorID':'7783172ce39cd663','fullDate':'2019/01/05'}, {'visitorID':'1834494d8537012d','fullDate':'2019/01/06'}, {'visitorID':'3321037b66164959','fullDate':'2019/01/06'} ]; /* Following solution from: https://stackoverflow.com/questions/36032179/remove-duplicates-in-an-object-array-javascript */ var uniq = new Set(visitData.map(e => JSON.stringify(e))); var res = Array.from(uniq).map(e => JSON.parse(e)); console.log(JSON.stringify(res)); </script> </body> </html> 1 Quote Share this post Link to post Share on other sites
iwato 18 Report post Posted June 9 Thank you, JMRKER, for your input. The problem was finally resolved using the following .filter( ) function. var uniqVals = visitData.filter((obj, index, self) => index === self.findIndex((other) => ( other.visitorID === obj.visitorID && other.fullDate === obj.fullDate )) ); Roddy Quote Share this post Link to post Share on other sites
justsomeguy 1,134 Report post Posted June 10 You almost had it with your changed code, it's just that e[comp1] && e[comp2] doesn't do what you expect or intended. Quote Share this post Link to post Share on other sites