iwato Posted June 7, 2019 Share Posted June 7, 2019 (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, 2019 by iwato Solution Provided Link to comment Share on other sites More sharing options...
justsomeguy Posted June 7, 2019 Share Posted June 7, 2019 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 Link to comment Share on other sites More sharing options...
iwato Posted June 7, 2019 Author Share Posted June 7, 2019 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 Link to comment Share on other sites More sharing options...
iwato Posted June 7, 2019 Author Share Posted June 7, 2019 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 Link to comment Share on other sites More sharing options...
justsomeguy Posted June 7, 2019 Share Posted June 7, 2019 Are you referring to code that was edited into your first post? Link to comment Share on other sites More sharing options...
iwato Posted June 7, 2019 Author Share Posted June 7, 2019 Yes! Link to comment Share on other sites More sharing options...
justsomeguy Posted June 7, 2019 Share Posted June 7, 2019 Add output statements similar to what I have, you should see why it's not comparing things the way you expect. Link to comment Share on other sites More sharing options...
iwato Posted June 8, 2019 Author Share Posted June 8, 2019 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 Link to comment Share on other sites More sharing options...
JMRKER Posted June 9, 2019 Share Posted June 9, 2019 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 Link to comment Share on other sites More sharing options...
iwato Posted June 9, 2019 Author Share Posted June 9, 2019 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 Link to comment Share on other sites More sharing options...
justsomeguy Posted June 10, 2019 Share Posted June 10, 2019 You almost had it with your changed code, it's just that e[comp1] && e[comp2] doesn't do what you expect or intended. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now