2013-01-21 80 views
1

用戶將在textarea中輸入各種連續字符。每個換行符都會顯示一個新的序列號。一些要求/限制:textarea重複字符串檢查忽略前導和尾隨空格

  • 不允許使用前導和尾隨空格。
  • 串行內的空白是可以的。
  • 空白連續字符不允許
  • 我寧願不使用JQuery。
  • 存儲重複項,以便它們可以顯示給用戶。

基於我的測試,我有一個工作解決方案。我想確保我不會錯過或忽略任何東西。我的問題是:

  • 有沒有更有效的方法來檢查重複?
  • 是否有任何明顯的測試案例,我的解決方案無法抓住?

工作實施例http://jsbin.com/ivusuj/1/

function duplicateCheck() { 
    var output = document.getElementById('Output'); 
    output.innerHTML = ''; 
    var duplicateSerials = []; 
    var count = 0; 
    var textArea = document.getElementById('Serials'); 
    var serials = textArea.value.trim().split(/ *\n */); 

    for(var i = 0;i < serials.length;i++){ 
     var serial = serials[i]; 

     if(serials.indexOf(serial) != serials.lastIndexOf(serial) && 
     duplicateSerials.indexOf(serial) == -1 && serial !== '') {   
     duplicateSerials.push(serial); 
     } 

    }  

    // For testing 
    output.innerHTML = '<pre>Serials:\t' + serials.toString() + "<br />" + 
        'Duplicates:\t' + duplicateSerials.toString() + "<br>" + 
        '</pre>'; 
} 

注:以上爲客戶端檢查。服務器端也會執行相同的檢查,以確保數據有效。


更新

解決方案比較:http://jsbin.com/ivusuj/4/edit

+0

我知道這是挑剔的,但只是你可能想要考慮的事情,如果你要分享代碼。通常對於像這樣的函數,您希望以小寫字母開頭。這似乎是慣例,即用大寫字母開頭的名字是爲了要實例化的函數而保留的(即用作「類」的函數)。 –

+0

不用擔心;我很欣賞這個建議。我實際上已經這樣做了,然後改變了它。 – JSuar

回答

1

我認爲,如果你使用的對象,以確定你見過哪個連續你會得到顯著更好的性能。更接近於此:

var seen = {}; 
for (var i = 0, j = serials.length; i < j; ++i) { 
    var serial = serials[i]; 
    if (seen.hasOwnProperty(serial)) { 
    // Dupe code goes here. 
    continue; 
    } 
    // Can't be a duplicate if we get to this point. 
} 

雖然這不適用於使用句號的連續劇。

+0

我仍然會考慮如何調整你的方法來使用一個Object來進行查找,即使你不用這個確切的解決方案(創建一個連續的散列並將它們放入對象中,例如[我意識到,有點矯枉過正])。你目前的'serials.indexOf(serial)!= serials.lastIndexOf(serial)'的上界非常靠近O(n^2)。 –

2

我放在一起的jsfiddle她:http://jsfiddle.net/wrexroad/yFJjR/3/

其實檢查重複這種方式是非常低效。

而不是檢查重複項,這只是將屬性添加到屬性的名稱是串行的對象。然後打印出所有的屬性名稱。

這種方式如果你有重複,它只會創建屬性,然後覆蓋它。

下面是函數:

function duplicateCheck() { 
    var output = document.getElementById('Output'); 
     output.innerHTML = ''; 

    var textArea = document.getElementById('Serials'); 
    var inputSerials = 
     textArea.value.trim().split(/ *\n */); 
    var outputSerials = new Object(); 

    for(var i = 0;i < inputSerials.length;i++){ 
     var serial = inputSerials[i]; 

     //build an object whose properties are serials 
     //if the serial exists, incremint a counter 
     if(outputSerials[serial]){ 
      outputSerials[serial]++; 
     }else{ 
      outputSerials[serial] = 1; 
     } 
    }  

    output.innerHTML = 
     'Serials: <br />'; 

    for(var i in outputSerials){ 
     output.innerHTML += i + " "; 
    } 

    output.innerHTML += 
     '<br /><br />Duplicate Serials: <br />'; 

    for(var i in outputSerials){ 
    //check to see if we have any duplicates 
     if(outputSerials[i] > 1){ 
      output.innerHTML += i + " "; 
     } 
    } 
} 
+0

這個解決方案肯定更快,但我將如何跟蹤重複的連續劇?我想警告用戶重複序列(s)並顯示它們。從可用性的角度來看,這很重要。 – JSuar

+0

我沒有意識到這是一個要求。我會修改它。給我一分鐘或三分鐘...... –

+0

其實,使用g.d.d.c代碼我能夠達到這個要求。它跟隨你的代碼很簡單。 – JSuar

0

下面就來過濾掉重複的解決方案。

function formatInput() { 
    var arrUnique = [], dups = [], 
    str = document.getElementById('Serials').value 
     .replace(/\r\n?/g,'\n') 
     // normalize newlines - not sure what PC's 
     // return. Mac's are using \n's 
     .replace(/(^((?!\n)\s)+|((?!\n)\s)+$)/gm,'') 
     // trim each line 
     .replace(/^\n+|\n+$|\n+(?=\n(?!\n))/g,''), 
     // delete empty lines and trim the whole string 
    arr = str.length ? str.split(/\n/) : []; 
    // split each line, if any 
    for (var i = 0; i < arr.length; i++) { 
     if (arrUnique.indexOf(arr[i]) == -1) 
      arrUnique.push(arr[i]); 
     else dups.push(arr[i]); 
    } 
    //document.getElementById('Serials').value = arrUnique.join('\n'); 
    console.log('serials:', arr); 
    console.log('unique:', arrUnique); 
    console.log('duplicates:', dups); 
} 
相關問題