Use reduce for getting the result.
var arr = [["apple","ghana",15],["apple","brazil",16],["orange","nigeria",10],["banana","bangladesh",20],["banana","ghana",6]];
const res = arr.reduce((a, c) => {
if (!a.find(v => v[0] === c[0])) {
a.push(c);
}
return a;
}, []);
console.log(res);
.as-console-wrapper {
min-height: 100% !important;
top: 0;
}
Answer from Sajeeb Ahamed on Stack OverflowUse reduce for getting the result.
var arr = [["apple","ghana",15],["apple","brazil",16],["orange","nigeria",10],["banana","bangladesh",20],["banana","ghana",6]];
const res = arr.reduce((a, c) => {
if (!a.find(v => v[0] === c[0])) {
a.push(c);
}
return a;
}, []);
console.log(res);
.as-console-wrapper {
min-height: 100% !important;
top: 0;
}
You could take a Set and filter the array by a check if the value exists or not.
If exist reject the element.
If not, add the value to the set and take the element.
var array = [["apple", "ghana", 15], ["apple", "brazil", 16], ["orange", "nigeria", 10], ["banana", "ghana", 6]],
seen = new Set,
result = array.filter(([value]) => !seen.has(value) && seen.add(value));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
How to get only unique items in a multidimensional array with JavaScript/jquery? - Stack Overflow
javascript - Find a unique item based on two values in multi-dimensional array - Stack Overflow
jquery - Unique value in multidimentional array in javascript - Stack Overflow
javascript - How to Count Unique Arrays in a Multidimensional Array - Stack Overflow
Try this:
var item = collection.filter(function(collect) {
return collect[0] == sourceId && collect[1] == targetId;
});
Again, like I said in the comments, it would better if you change your data structure to an array of objects with named keys then you can do this much more readable:
return collect.sourceId == sourceId && collect.targetId == targetId;
If you need compatibility to older browsers, since .filter() is supported only by IE9 you can also loop through the elements of the array(or write the implementation of filter, provided by MDN).
var item = [];
for (var i = 0; i < collection.length; i++) {
var coll = collection[i];
if (coll[0] == sourceId && coll[1] == targetId) item.push(coll);
}
You can map each inner array to a stringified version of itself using .map(JSON.stringified). Now, using this new array, you can reduce it to an object which contains each stringified array as a key, and keeps the number of occurrences as its value. While reducing, you can check whether or not the object's key has already been set using a[k] = (a[k] || 0)+1. If it has already been set, it will use the current number stored at the key and increment it by 1, if it hasn't already been set it will set it equal to zero, and then increment it by 1 (which acts as the default value for any new keys (i.e newly seen arrays)).
Lastly, you can get the keys from your object which represent each unique array as strings using Object.keys(), and parse each back into a non-stringified array using JSON.parse. You can get the counts from your array by using Object.values() as this will get all the values (ie: the counters) of your reduced object and put them into an array.
See example below:
const arr = [[1,2], [1,2], [1,3], [1,4], [1,4], [1,4]];
const arr_str = arr.map(JSON.stringify);
const arr_map = arr_str.reduce((a, k) => (a[k] = (a[k] || 0) + 1, a), {});
const uniqueArrays = Array.from(Object.keys(arr_map), JSON.parse);
const theCount = Object.values(arr_map);
console.log(uniqueArrays);
console.log(theCount);
you can use below code
var arr = [[1,2], [1,2], [1,3], [1,4], [1,4], [1,4]];
var uniqueArrays = [];
var theCount = [];
var test = [], obj ={};
arr.forEach(val => {
if(test.indexOf(val.toString()) == -1){
test.push(val.toString());
obj[val.toString()] = 1;
uniqueArrays.push(val);
}else{
obj[val.toString()] += 1;
}
})
theCount = Object.values(obj);
console.log(uniqueArrays);
console.log(theCount);
Hope it will help you.
Quick and dirty solution, assuming the data is small.
On each iteration, convert the row to a string. Use a dictionary to store the string with a value of True, if it is not already in the map. Also, add it to your output array. If it is already in the dictionary, go to the next item.
Example:
var d = {};
var out = [];
for( var i = 0; i < items.length; i++ ) {
var item = items[i];
var rep = item.toString();
if (!d[rep]) {
d[rep] = true;
out.push(item);
}
}
// out has the result
You have to loop two (or three times):
- Loop through all "rows", from beginning to the end
Loop again, through all "rows", from beginning to the end
- If the lists are equal, ignore it
- Otherwise,
Loop through all "columns":
- If the values are not equal, jump to the parent loop.
- After the loop, remove the element using the
.splicemethod.
Demo: http://jsfiddle.net/EuEHc/
Code:
for (var i=0; i<items.length; i++) {
var listI = items[i];
loopJ: for (var j=0; j<items.length; j++) {
var listJ = items[j];
if (listI === listJ) continue; //Ignore itself
for (var k=listJ.length; k>=0; k--) {
if (listJ[k] !== listI[k]) continue loopJ;
}
// At this point, their values are equal.
items.splice(j, 1);
}
}
Here's a much cleaner solution for ES6 that I see isn't included here. It uses the Set and the spread operator: ...
var a = [1, 1, 2];
[... new Set(a)]
Which returns [1, 2]
Or for those looking for a one-liner (simple and functional) compatible with current browsers:
let a = ["1", "1", "2", "3", "3", "1"];
let unique = a.filter((item, i, ar) => ar.indexOf(item) === i);
console.log(unique);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Update 2021 I would recommend checking out Charles Clayton's answer, as of recent changes to JS there are even more concise ways to do this.
Update 18-04-2017
It appears as though 'Array.prototype.includes' now has widespread support in the latest versions of the mainline browsers (compatibility)
Update 29-07-2015:
There are plans in the works for browsers to support a standardized 'Array.prototype.includes' method, which although does not directly answer this question; is often related.
Usage:
["1", "1", "2", "3", "3", "1"].includes("2"); // true
Pollyfill (browser support, source from mozilla):
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(searchElement, fromIndex) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If len is 0, return false.
if (len === 0) {
return false;
}
// 4. Let n be ? ToInteger(fromIndex).
// (If fromIndex is undefined, this step produces the value 0.)
var n = fromIndex | 0;
// 5. If n β₯ 0, then
// a. Let k be n.
// 6. Else n < 0,
// a. Let k be len + n.
// b. If k < 0, let k be 0.
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(searchElement, elementK) is true, return true.
// c. Increase k by 1.
// NOTE: === provides the correct "SameValueZero" comparison needed here.
if (o[k] === searchElement) {
return true;
}
k++;
}
// 8. Return false
return false;
}
});
}
const arr = [[7,3], [7,3], [3,8], [7,3], [7,3], [1,2]];
function multiDimensionalUnique(arr) {
var uniques = [];
var itemsFound = {};
for(var i = 0, l = arr.length; i < l; i++) {
var stringified = JSON.stringify(arr[i]);
if(itemsFound[stringified]) { continue; }
uniques.push(arr[i]);
itemsFound[stringified] = true;
}
return uniques;
}
const uniques = multiDimensionalUnique(arr);
console.log(uniques);
Explaination:
Like you had mentioned, the other question only dealt with single dimension arrays which you can find via indexOf. That makes it easy.
Multidimensional arrays are not so easy, as indexOf doesn't work with finding arrays inside.
The most straightforward way that I could think of was to serialize the array value, and store whether or not it had already been found.
It may be faster to do something like stringified = arr[i][0]+":"+arr[i][1], but then you limit yourself to only two keys.
This requires JavaScript 1.7:
var arr = [[7,3], [7,3], [3,8], [7,3], [7,3], [1,2]];
arr.map(JSON.stringify).filter((e,i,a) => i === a.indexOf(e)).map(JSON.parse)
// [[7,3], [3,8], [1,2]]
Credit goes to jsN00b for shortest version.