Jump to content

Eliminating Objects of an Array


iwato

Recommended Posts

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 by iwato
Solution Provided
Link to comment
Share on other sites

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?

  • Like 1
Link to comment
Share on other sites

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

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

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

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>
	

 

  • Like 1
Link to comment
Share on other sites

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...