2012-01-02 77 views
3

我试图找到在Javascript数组中只出现一次的项目。在下面的数组:查找在Javascript数组中只出现一次的项目

['txfa2','txfa9','txfa2','txfa1','txfa3','txfa4','txfa8','txfa9','txfa2','txfa8'] 

结果应该是:

['txfa1','txfa3','txfa4'] 

我目前使用jQuery和.sort().each()功能。这样做有更聪明还是更好的方法?你知道任何jQuery插件可以用更少的代码行来做到这一点。

<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> 
+0

请介绍一下你在你的情况下配对的意思。 – 2012-01-02 09:50:49

回答

4

简明的方式做到这一点:

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; 
}; 

演示:http://jsfiddle.net/ThinkingStiff/C849F/

这里的非重复这个问题的答案的显示这种方法(蓝色)与其他方法相同的性能(即实际工作)。

性能:http://jsperf.com/find-array-singles/3

enter image description here

+0

简洁,但O(n^2) – Alnitak 2012-01-02 14:36:56

+0

@Alnitak它比你在类似问题的样本上呈现的速度快得多:http://jsperf.com/find-array-singles/3 – ThinkingStiff 2012-01-02 20:10:23

+0

好奇 - 是的,关于虽然速度很快,但我希望我的速度在更大的阵列上更快,因为它应该是O(n + nlogn) - 但奇怪的是Safari太慢了! – Alnitak 2012-01-02 21:43:27

4

一个简单的方法将利用Javascript的内建对象。让一个对象充当集合中每个项目的计数器,然后遍历它以检查哪个项目具有计数器1.

它相当快;

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) 
+0

他/她询问的元素只出现一次,例如'txfa2'应该不会出现在结果中。 – 6502 2012-01-02 09:56:45

+0

@ 6502更新了代码。 – qiao 2012-01-02 10:00:08

0
/** 
* 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)); 

看到example

或使用:jQuery.unique([]);

+2

该示例返回'1,2,4,5,4' – Bakudan 2012-01-02 09:53:48

+1

是的,它显然需要对阵列进行预先排序。 – Alnitak 2012-01-02 09:55:52

+0

@Bakudan,thx固定! – 2012-01-02 10:07:54

5

下面是使用ES5的功能的方法,基于使用的对象进行计数的次数发生的每个值的示例:

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); 
    }); 
} 

在工作演示

+0

也许使用Object.keys而不是Object.getOwnPropertyNames会更好? – 2012-01-02 11:25:01

+0

@Amaan'getOwnPropertyNames()'更安全。 – Alnitak 2012-01-02 13:52:14

+0

@nnitak使用'.keys',因为'o [k]'永远不会变成非枚举属性 – Raynos 2012-01-02 14:05:00

1

通过“找到独特的项目”我相信你的意思是“发现不重复的项目”(相对于“找不同的值”)?另外,我不明白为什么你的haspair变量是一个字符串:你的样本数据有多对。无论如何...

有很多方法可以做到这一点,但我会用一个对象来计算每个不同的值。这使得生成非重复项目的数组和重复项目的数组以及不同值的数组变得容易。显然,如果你不需要全部三个,你可以省略那些你不关心的,但是我已经在下面显示了所有三个,这就是为什么它看起来可能比你想要的长。当然,如果你想要计算任何类别中的数量,只需使用数组长度即可。

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); 
} 

注:我已经写在上面普通的JavaScript,而无需使用可能不被旧的浏览器支持的新阵列的功能。很明显,你可以采取的基本算法,并使用jQuery通过初始阵列和/或working属性进行迭代,或者你可以使用.forEach(),如果你不关心IE 9 <等

+0

不明原因的投票?谢谢。 – nnnnnn 2012-01-03 00:06:06

相关问题