1

I have the following code snippet, where I want original array (filters) to be filtered and get unique filters array.

I think I tried all the methods possible and it (uniqueFilters array) is still same 11 member original array.

Whats wrong?

How can I ensure that this array is actually filtered down to just a few unique elements in it? (they all are coming from the same place and are the same)

UPDATE: - the answer successfully resolved the issue in js code. - in the actual app I had to also deal with typescript to use the suggested answer. So maybe will help someone:

let newUniqueFilters = Array.from(new Map(filters.map(f => [f._id, f] as [string, any])).values());

var filters = [{
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}, {
	"_id": "filter1",
	"filterIndex": 1,
	"filterLabel": "Blur",
	"filterURL": "url(#filter1)",
	"filterEffects": [{
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 5
		}]
	}]
}, {
	"_id": "filter2",
	"filterIndex": 2,
	"filterLabel": "Shadow",
	"filterURL": "url(#filter2)",
	"filterEffects": [{
		"name": "feOffset",
		"attributes": [{
			"name": "dx",
			"value": 20
		}, {
			"name": "dy",
			"value": 20
		}, {
			"name": "result",
			"value": "offOut"
		}, {
			"name": "in",
			"value": "SourceAlpha"
		}]
	}, {
		"name": "feGaussianBlur",
		"attributes": [{
			"name": "stdDeviation",
			"value": 7
		}, {
			"name": "in",
			"value": "offOut"
		}, {
			"name": "result",
			"value": "blurOut"
		}]
	}, {
		"name": "feBlend",
		"attributes": [{
			"name": "mode",
			"value": "normal"
		}, {
			"name": "in2",
			"value": "blurOut"
		}, {
			"name": "in",
			"value": "SourceGraphic"
		}]
	}]
}]

// first method:
var uniqueFilters = [];
for(let i = 0; i < filters.length; i++) {
    if(uniqueFilters.indexOf(filters[i]) == -1){
        uniqueFilters.push(filters[i])
    }
}
console.log("first method")
console.log("original array length:" + filters.length)
console.log("unique array length:" + uniqueFilters.length)

// second method:
//var uniqueFilters = filters.filter(function(elem, index, self) {
//        return index == self.indexOf(elem);
//});
//console.log("second method")
//console.log("original array length:" + filters.length)
//console.log("unique array length:" + uniqueFilters.length)

// suggested method 1:
var newUniqueFilters = Array.from(new Map(filters.map(f => [f._id, f])).values());
console.log(newUniqueFilters)

2
  • Object comparison is not based on object content, it's based on identity. An object is always !== every other object. Commented Mar 1, 2018 at 16:32
  • so I can't solve my problem this way then? ouch Commented Mar 1, 2018 at 16:34

3 Answers 3

3

You can use a Map:

filters = Array.from(new Map(filters.map(f => [f._id, f])).values());

This assumes that it is enough to compare the _id values, which uniquely identify filters.

Note that comparing objects themselves (with indexOf or similar methods) will never show duplicates, as all the objects are different references (copies), even though they look the same. In general {} === {} is always false.

Sign up to request clarification or add additional context in comments.

5 Comments

Nice solution. But are there any advantages to passing it to a new instance of the Map class? Why not simply do: filters = filters.map(f => [f._id, f]); Is it for readability purposes?
@AlexanderEdwards, the new Map( ) will collapse items with the same id (i.e. with the same first value in the pairs), while the .map() alone will not reduce the number of items you get in your result.
Hey yo, this worked, but more importantly I wanted to thank you for explanation about objects comparison, now I see where my bugs are lol.
so feels like when it comes to objects - best practice is to ID those and then use that as a basis for copmparison.
Indeed, it is like that.
1

It's not working because every element in filter array has different memory location and object are compared by the memory location.

So every time you compare that object exist of filter array in uniqueFilters, it simply doesn't exist because every object has different memory location. so it will push every element in uniqueFilters.

Comments

0

Try changing this line

if(uniqueFilters.indexOf(filters[i]) == -1){ to if(uniqueFilters.indexOf(filters[i]) === -1){

If not worikingn you can too try comparing a specific attibute to all uniqueFilter

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.