I\'m trying to find the items that appear only one time in a Javascript array. In the following array:
[\'txfa2\',\'txfa9\',\'txfa2\',\'txfa1\',\'txfa3\',\'t
a simple approach will be making advantage of Javascript's builtin object. Let an object act as a counter for each item in the collection, then iterate over it to check which item has a counter of 1.
it's quite fast;
var items = ['txfa2', 'txfa9', 'txfa2', 'txfa1', 'txfa3', 'txfa4', 'txfa8', 'txfa9', 'txfa2', 'txfa8'],
result = [],
i,
k,
container = {};
for (i = 0; i < items.length; ++i) {
if (items[i] in container) {
container[items[i]]++;
} else {
container[items[i]] = 1;
}
}
for (k in container) {
if (container[k] == 1) {
result.push(k);
}
}
console.log(result)
A concise way to do it:
function singles(array) {
for (var index = 0, single = []; index < array.length; index++) {
if (array.indexOf(array[index], array.indexOf(array[index]) + 1) == -1)
single.push(array[index]);
};
return single;
};
var items = ['txfa2', 'txfa9', 'txfa2', 'txfa1', 'txfa3', 'txfa4', 'txfa8', 'txfa9', 'txfa2', 'txfa8'];
console.log(singles( items ))
Demo: http://jsfiddle.net/ThinkingStiff/C849F/
Here's the performance of the non-duplicate answers to this question (that actually work) showing this method (blue) is comparable with the other methods.
Performance: http://jsperf.com/find-array-singles/3
/**
* Array.uniq();
*
* @author: Alexander Guiness
* @param: {Array}
* @return: {Array} An array of unique values
* @licence: MIT
* @use: Array.uniq([1,1,1,1,2,2,2,4,5,5,4]); //1,2,4,5
* @date: Mon Jul 26 10:00:00 2011
*/
(function($) {
'use strict';
if(!$.uniq) {
$.uniq = function(array) {
if(Object.prototype.toString.call(array) !== '[object Array]')
return -1;
var i = array.length;
array.sort();
while(i--) {
if(array[i] == array[i-1]) {
array.splice(i, 1);
}
}
return array;
}
}
}(Array));
see the example
or use: jQuery.unique([]);
Here's an example using ES5's functional methods, based on using an object to count the number of times each value occurs:
function uniq(a) {
// create a map from value -> count(value)
var counts = a.reduce(function(o, k) {
o[k] = o[k] ? o[k] + 1 : 1;
return o;
}, {});
// find those that only appeared once
return Object.keys(counts).filter(function(k) {
return (counts[k] === 1);
});
}
console.log(
uniq(['txfa2', 'txfa9', 'txfa2', 'txfa1', 'txfa3', 'txfa4', 'txfa8', 'txfa9', 'txfa2', 'txfa8'])
)
Working demo at http://jsfiddle.net/alnitak/shyce/
By "find the unique items" I believe you mean "find items that are not repeated" (as compared to "find distinct values")? Also, I don't understand why your haspair
variable is a string: your sample data has more than one pair in it. Anyway...
There are lots of ways to do this, but I'd use an object to make a count for each distinct values. That makes it easy to generate an array of the non-repeated items and an array of the repeated items, and an array of the distinct values. Obviously if you don't need all three you omit the ones you don't care about, but I've shown all three below which is why it may look a bit longer than you wanted. Of course if you want a count of how many are in any category you just use the array length.
var items = ['txfa2', 'txfa9', 'txfa2', 'txfa1', 'txfa3', 'txfa4', 'txfa8', 'txfa9', 'txfa2', 'txfa8'];
var working = {},
hasPairs = [],
noPairs = [],
distinct = [],
i, k;
for (i=0; i < items.length; i++)
if (working.hasOwnProperty(items[i]))
working[items[i]]++;
else
working[items[i]] = 1;
for (k in working) {
if (working[k] > 1)
hasPairs.push(k);
else
noPairs.push(k);
distinct.push(k);
}
Note: I've written the above with plain JavaScript, without using newer array functions that might not be supported by older browsers. Obviously you can take the basic algorithm and use jQuery to iterate through the initial array and/or the properties of working
, or you can use .forEach() if you don't care about IE < 9, etc.