2011-12-18 161 views
0

我想要一個與javascript字符串數組進行比較的函數,並將不匹配的值保存到新數組中。目前即時通訊使用嵌套的jQuery的foreach。但我認爲有比這更好的方法?比較javascript數組

$.each(imagesInUploadsFolder, function(i, outervalue){ 
      $.each(imagesInDatabaseTable, function(i, innervalue){ 

       if(outervalue == innervalue){ 
        //match in both arrays... 
       } 

      }); 
     }); 
+0

顯然你想使用'==='運算符進行比較... – 2011-12-18 01:03:40

回答

1

以下是使用JSON對象並且不使用jQuery的方法,但$.inArray()應該可以正常工作:

var imagesInUploadsFolder = [ 
    '/path/to/img1.png', 
    '/path/to/img2.png', 
    '/path/to/img3.png' 
]; 
var imagesInDatabaseTable = [ 
    '/path/to/img1.jpg', 
    '/path/to/img2.png', 
    '/path/to/img4.png' 
]; 

var database_json = JSON.stringify(imagesInDatabaseTable); 

for (var i = 0; i < imagesInUploadsFolder.length; i++) { 
    console.log(imagesInUploadsFolder[i] + ' in ' + database_json); 
    if (database_json.indexOf(imagesInUploadsFolder[i]) > -1) { 
     console.log('In database: ' + imagesInUploadsFolder[i]); 
    } else { 
     console.log('Not in database: ' + imagesInUploadsFolder[i]); 
    } 
} 

http://jsfiddle.net/7nJPW/1/

編輯

其實,不需要JSON方法(?):

for (var i = 0; i < imagesInUploadsFolder.length; i++) { 
    console.log(imagesInUploadsFolder[i] + ' in ' + imagesInDatabaseTable); 
    if (imagesInDatabaseTable.indexOf(imagesInUploadsFolder[i]) > -1) { 
     console.log('In database: ' + imagesInUploadsFolder[i]); 
    } else { 
     console.log('Not in database: ' + imagesInUploadsFolder[i]); 
    } 
} 

http://jsfiddle.net/7nJPW/2/

+0

謝謝,忘了提及我只是在尋找錯配。有點修改:) http://jsfiddle.net/7nJPW/1/ – Johan 2011-12-18 01:09:03

+0

@Johan - 你可以放棄'JSON'部分,這是不必要的。看我的編輯。 – 2011-12-18 01:10:08

+0

@Johan - 這會更好(參見'c_uploads'):http://jsfiddle.net/7nJPW/4/ – 2011-12-18 01:12:16

1

這是最簡單的方法我能想到的,現在:)

$.each(imagesInUploadsFolder, function(i, outervalue){ 
     if($.inArray(imagesInDatabaseTable,outervalue)>-1){ 
       //my operation 
     } 
    } 

FYI:其實inArray返回innermatch否則返回-1指數。只是開始你需要它。

+0

爲什麼在'.forEach()'和'.indexOf()'完成工作......'時使用jQuery ' – 2011-12-18 01:01:45

+0

他已經在使用jquery,所以爲什麼不用jquery風格寫所有東西.. :) – 2011-12-18 01:03:49

+0

因爲它表現更好。 – 2011-12-18 01:05:33

1

爲什麼不使用純JavaScript的foreach?

for (var i = 0; i < innervalue.length; i++) { 
    for (var j = 0; j < outervalue.length; j++){ 
     if (innervalue[i] === outervalue[j]) 
      // match 
    } 
} 
2

如何:

arr1.forEach(function (elem) { 
    if (arr2.indexOf(elem) > -1) { 
     // match... 
    } 
}); 

其中arr1arr2是你的兩個數組...

(順便說一句,ES5墊片爲IE8,當然...)

+0

呵呵。 http://jsfiddle.net/7nJPW/3/ – 2011-12-18 01:08:48

+0

@JaredFarrish是嗎?它是什麼? – 2011-12-18 01:14:24

+0

+1,但是您必須爲每個**和** indexOf都填充,對嗎? – 2011-12-18 01:15:05

0

無論你使用jQuery或for循環,直接比較將是O(n ),因爲您需要將一個數組的每個元素與另一個數組的每個元素進行比較。

如果對象具有可比性,可以使用合適的比較函數對項目進行排序,然後同時循環兩個數組,檢查一個元素是否小於另一個。如果您熟悉合併排序,這與合併步驟非常相似。假設比較函數爲O(1),排序爲O(n log(n)),並且類似合併的比較循環爲O(n),總時間複雜度爲O(n log(n)),其中「n」是較大陣列的長度。

imagesInUploadsFolder.sort(imgCmp); 
    imagesInDatabaseTable.sort(imgCmp); 
    // diff will hold the difference of the arrays 
    var diff = []; 
    var i=0, j=0, cmp; 
    while (i < imagesInUploadsFolder.length && j < imagesInDatabaseTable.length) { 
     cmp = cmp(imagesInUploadsFolder[i], imagesInDatabaseTable[j]); 
     if (cmp < 0) { 
      // up[i] < db[j] 
      ++i; 
      diff.append(imagesInUploadsFolder[i]); 
     } else if (cmp > 0) { 
      // up[i] > db[j] 
      ++j; 
      diff.append(imagesInDatabaseTable[j]); 
     } else { 
      // up[i] == db[j] 
      ++i; ++j; 
     } 
    } 
    // one of the arrays may still have items; if so, loop over it and add the items 
    if (i < imagesInUploadsFolder.length) { 
     for (; i < imagesInUploadsFolder.length; ++i) { 
      diff.append(imagesInUploadsFolder[i]); 
     } 
    } else if (j < imagesInDatabaseTable.length)) { 
     for (; i < imagesInDatabaseTable.length; ++i) { 
      diff.append(imagesInDatabaseTable[i]); 
     } 
    } 
    // diff now holds items that are in only one of the two arrays. 

如果可以定義一個合適object ID function,則可以創建一個保存一組元件的輔助數據結構。如果訪問對象屬性是O(f(n))(對於哈希,f≈1;對於平衡樹,f = log(n)),那麼這個方法是O(n * f(n)),所以它應該有沒有比排序和比較方法更糟糕的複雜性。未經測試和低效執行:

function Set(from) { 
    this.elements = {}; 
    this.size = 0; 
    if (from) { 
     for (var i=0; i < from.length) { 
      this.add(from[i]); 
     } 
    } 
} 
Set.prototype.each = function(f) { 
    var eltId; 
    foreach (eltId in this.elements) { 
     f(this.elements[eltId], eltId); 
    } 
}; 
Set.prototype.clone = function() { 
    var clone = new Set(); 
    this.each(function(obj, id) { 
     clone.add(obj); 
    }); 
    return clone; 
}; 
Set.prototype.contains = function(obj) { 
    return obj.uniqueId() in this.elements; 
}; 
Set.prototype.add = function(obj) { 
    var objId = obj.uniqueId(); 
    if (! (objId in this.elements)) { 
     ++this.size; 
     this.elements[objId] = obj; 
    } 
    return this; 
}; 
Set.prototype.remove = function(obj) { 
    var objId = obj.uniqueId(); 
    if (objId in this.elements) { 
     --this.size; 
     delete this.elements[objId]; 
    } 
    return this; 
}; 
Set.prototype.union = function(other) { 
    other.each(function(elt, id) { this.add(elt); }); 
    return this; 
}; 
Set.prototype.sub = function(other) { 
    other.each(function (elt, id) { 
     this.remove(elt); 
    }); 
    return this; 
}; 
Set.prototype.diff = function(other) { 
    var mine = this.clone(); 
    mine.sub(other); 
    var others = other.clone(); 
    others.sub(this); 
    mine.union(others); 
    return mine; 
}; 
Set.prototype.toArray = function(obj) { 
    var arr = []; 
    this.each(function(elt, id) { 
     arr.append(elt); 
    }); 
    return arr; 
}; 

var uploadsSet = new Set(imagesInUploadsFolder), 
    dbSet = new Set(imagesInDatabaseTable), 
    imagesInJustOne = uploadsSet.diff(dbSet); 

如果你想同時得到工會和數組的區別,你可以在Set定義一個適當的方法,以更有效地計算,而不是使用Set.diffSet.union分開它們。

+0

Outis,這是一個Rainman的時刻嗎?這是......一個很好的答案。 – 2011-12-18 01:34:22