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','txfa4','txfa8','txfa9','txfa2','txfa8']
The result should be:
['txfa1','txfa3','txfa4']
I'm currently using the .each()
function in jQuery and .sort()
. Is there a smarter or better way on doing this? Do you know of any jQuery plugin that can do this in fewer lines of code.
<script src="../../js/jq.js"></script>
<script>
var items = ['txfa2', 'txfa9', 'txfa2', 'txfa1', 'txfa3', 'txfa4', 'txfa8', 'txfa9', 'txfa2', 'txfa8'];
var nopairs = []; //should contain only txfa1, txfa3, txfa4
var haspair = '';//contains the item which has pairs
var haspair_ctr = 0;
var nopair_ctr = 0;
var arranged = items.sort();
$(arranged).each(function(index){
if(index != arranged.length){
if(arranged[index] != arranged[index + 1] && arranged[index] != haspair){
nopairs[nopair_ctr] = arranged[index];
nopair_ctr++;
}else{
haspair = arranged[index];
}
}
});
console.log(nopairs);
</script>
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','txfa4','txfa8','txfa9','txfa2','txfa8']
The result should be:
['txfa1','txfa3','txfa4']
I'm currently using the .each()
function in jQuery and .sort()
. Is there a smarter or better way on doing this? Do you know of any jQuery plugin that can do this in fewer lines of code.
<script src="../../js/jq.js"></script>
<script>
var items = ['txfa2', 'txfa9', 'txfa2', 'txfa1', 'txfa3', 'txfa4', 'txfa8', 'txfa9', 'txfa2', 'txfa8'];
var nopairs = []; //should contain only txfa1, txfa3, txfa4
var haspair = '';//contains the item which has pairs
var haspair_ctr = 0;
var nopair_ctr = 0;
var arranged = items.sort();
$(arranged).each(function(index){
if(index != arranged.length){
if(arranged[index] != arranged[index + 1] && arranged[index] != haspair){
nopairs[nopair_ctr] = arranged[index];
nopair_ctr++;
}else{
haspair = arranged[index];
}
}
});
console.log(nopairs);
</script>
Share
Improve this question
edited Jan 3, 2012 at 0:33
ThinkingStiff
65.4k30 gold badges147 silver badges241 bronze badges
asked Jan 2, 2012 at 9:44
Wern AnchetaWern Ancheta
23.3k38 gold badges105 silver badges140 bronze badges
1
- Please brief what you mean by pairing in your case. – Abdul Munim Commented Jan 2, 2012 at 9:50
5 Answers
Reset to default 6Here'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/alnitak/shyce/
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/ThinkingStiff/C849F/
Here's the performance of the non-duplicate answers to this question (that actually work) showing this method (blue) is parable with the other methods.
Performance: http://jsperf./find-array-singles/3
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)
By "find the unique items" I believe you mean "find items that are not repeated" (as pared 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.
/**
* 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([]);