2012-01-02 80 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

相關問題