2011-06-06 34 views
2

我有一個數組如何搜索數組中的值並在發現2個或更多個時刪除其中的一個值?

var aos = ["a","a","a","b","b","c","d","d"]; 

我想知道,如果它發現2個或更多的數組中的值相同的,我可以只刪除1項。因此,舉例來說,如果它發現

"a", "a"

它會刪除那些「一」

這是我當前的代碼之一:

var intDennis = 1; 
         for (var i = 0; i < aos.length; i++) { 
          while (aos[i] == aos[intDennis]) { 
           aos.splice(i, 1); 
           intDennis++; 
           console.log(aos[intDennis], aos[i]); 
          } 
          intDennis = 1; 
         } 

注:我的數組進行排序。

+0

我欣賞所有的答案,但它似乎有些偏離軌道,我需要一些幫助,只刪除一個值一個重複的值,而不是所有的重複值,所以如果我有3個「a」,我只想刪除其中的一個「a」。 我可能需要找到一種不同的方法,而不是刪除重複項,任何建議都會很棒。 – 2011-06-06 20:58:34

+0

只有重複時才需要刪除一個值嗎? – Briguy37 2011-06-06 21:01:53

+0

我已經更新了我的答案,以便您澄清需求。 – Yardboy 2011-06-06 21:18:11

回答

2

在更好地理解OP使用案例之後進行編輯。 更新瞭解決方案和小提琴測試,以在註釋中包含來自pst的建議。

(不是沒有,但這種方法並不需要原來的數組進行排序。)

嘗試......

var elements = []; 
var temp = {}; 
for (i=0; i<aos.length; i++) { 
    temp[aos[i]] = (temp[aos[i]] || 0) + 1; 
} 
for (var x in temp) { 
    elements.push(x); 
    for (i=0; i<temp[x]-2; i++) { 
     elements.push(x); 
    } 
} 

Fiddle Test

+1

+1(因爲這與桶排序的最後一個階段類似;-)但是,考慮簡化初始的temp-builder:'(x || 0)+ 1' - >'1',其中'x'是一個false-y值,包括'undefined'和'0'。 – 2011-06-06 21:38:59

+0

優秀 - 我不知道如何在JS中做到這一點 - 易於在我生活的紅寶石。 ;)tks – Yardboy 2011-06-06 22:05:49

+0

你救了我這麼頭痛一半!謝謝! – 2011-06-07 12:58:07

0

已更新的答案只取出1個重複:

假設每個對象將解決爲唯一的字符串,這裏有一個潛在的解決方案。第一次檢測到對象時,它將該對象的計數器設置爲1。如果它再次找到該對象,則將該元素拼接出來並遞增關聯的計數器。如果它多次發現這個元素,它就會讓它獨處。

var elements = {}; 
for (var i = 0; i < aos.length; i++) { 
    if(elements[aos[i]]){ 
     if(elements[aos[i]] == 1){ 
      aos.splice(i,1);//splice the element out of the array 
      i--;//Decrement the counter to account for the reduced array 
      elements[aos[i]]++;//Increment the count for the object 
     } 
    } else { 
     elements[aos[i]] = 1;//Initialize the count for this object to 1; 
    } 
} 

Here的測試小提琴爲此。

+0

這不起作用,因爲對象只有字符串作爲屬性值,所以,例如'[1,「1」]'會減少到'[1]'。同樣,'[「toString」]'會變成'[]'。 – gsnedders 2011-06-06 20:48:10

+0

@gsnedders是的,這隻有在值解析爲唯一字符串時纔有效。在他的例子中,他只有字符串,所以這個解決方案應該工作。 – Briguy37 2011-06-06 20:54:52

+0

@ Dennis Martinez現在回答更新,只刪除一個副本。 – Briguy37 2011-06-06 21:38:27

0

修改了例

function removeDuplicate(arr) { 
    var i = 1; 
    while(i < arr.length) { 
     if(arr[i] == arr[i - 1]) { 
      arr.splice(i, 1); 
     } 
     while(arr[i] == arr[i - 1] && i < arr.length) { 
      i += 1; 
     } 
     i += 1; 
    } 
    return arr; 
} 
alert(removeDuplicate(["a","a","a","b","b","c","d","d"])); 
+0

這將刪除所有重複,而不僅僅是一個。 http://jsfiddle.net/XKsWy/ - 當它應該是'[「a」,「a」,「b」時,結果是'[「a」,「b」,「c」,「d」]' 「,」c「,」d「]' – 2011-06-06 22:30:35

0

我不相信有沒有更好的方式在未排序的數組上執行此操作,而不是使用O(n^2)行爲的方法。鑑於ES5陣列內建(支持所有現代瀏覽器,但不是在IE之前IE9),以下工作:

aos.filter(function(value, index, obj) { return obj.indexOf(value) === index; })

0

我也不會發生變異的輸入 - 也就是說,不使用splice 。這將很好地簡化問題。這裏使用一個新的數組對象實際上可能是效率更高。這種方法利用了輸入數組排序的事實。

考慮:(jsfiddle demo

var input = ["a","a","a","b","b","c","d","d"] 
var result = [] 

for (var i = 0; i < input.length; i++) { 
    var elm = input[i] 
    if (input[i+1] === elm) { 
     // skip first element (we know next is dup.) 
     var j = i + 1 
     for (; input[j] === elm && j < input.length; j++) {  
      result.push(input[j]) 
     } 
     i = j - 1 
    } else { 
     result.push(elm) 
    } 
} 

alert(result) // a,a,b,c,d 

編碼愉快。


根據需要用自定義等式替換===。請注意,它是輸出中省略的第一項,可能並不總是「正確」。

1

因爲你說你有一個排序的數組,所以你只需要第二次找到一個元素。只需要一個splice()函數返回已刪除的元素,只是用它來刪除更多的那種元素。

此解決方案更多清潔高效

var aos = ["a","a","a","b","b","c","d","d"]; 
var lastRemoved = ""; 
for (var i = 1; i < aos.length; i++) { 
    if (aos[(i-1)] == aos[i] && lastRemoved != aos[i]) { 
     lastRemoved = aos.splice(i, 1); 
    } 
} 

代碼測試和工作。結果:[「a」,「a」,「b」,「c」,「d」]

+0

@ Dennis你可以在http://jsfiddle.net/L6CGQ/查看測試代碼 – 2011-06-07 14:47:12

相關問題