2012-07-09 18 views
3

是否有可能在Javascript中獲得關聯數組和常規數組的區別?如何獲得Javascript中的關聯數組和常規數組之間的區別?

Ex。

array1 = [5, 1, 3]; 
array2 = [1 => 15, 2 => 20, 3 => 10, 4 => 5, 5 =>50 ]; 

的區別是...

diff = [2 => 20, 4=> 5]; 
+5

你的第二個數組應該是一個對象,而不是一個數組(JavaScript不具有*關聯數組本身)。事實上,將上述內容粘貼到Chrome報告中的JavaScript控制檯中:「SyntaxError:Unexpected token>」更進一步:潛在的愚蠢,在:http://stackoverflow.com/questions/1187518/javascript-array-difference – 2012-07-09 00:21:15

+0

你的第二個數組isn沒有有效的JavaScript。 – 2012-07-09 00:22:38

+0

你的意思是第二個數組應該像... array2 [1] = 15? – JohnSmith 2012-07-09 00:25:25

回答

4

我認爲你的問題剛剛有了一個小錯字在你的array2聲明。這不是什麼大不了的事。

不管怎麼說,這是一個有點劈,但它給你想要的東西:

array1 = [5, 1, 3]; 
array2 = {1: 15, 2: 20, 3: 10, 4: 5, 5: 50}; 

var result = {}; 
for (var i in array2) { 
    if (array1.indexOf(+i) < 0) { 
     result[i] = array2[i]; 
    } 
} 

alert(JSON.stringify(result)); 

Working example

我的黑客是在indexOf呼叫+i,因爲你的「關聯的屬性數組「是字符串,但是您的array1包含數字。一元+從字符串中產生一個數字。有點駭人聽聞,但它是慣用的JavaScript慣例。

附錄

由於RobG指出,indexOf是ES5的方法,因此,如果您的JavaScript引擎是ES3或以下,則需要你自己實現indexOfAn example of how to do this is at MDN。或者,您可以通過單獨搜索數組來執行與indexOf等效的操作。

所有的

+0

+1爲+我黑客。 – 2012-07-09 01:16:09

+0

沒有ES5 * indexOf *方法的數組(例如IE 8和更低版本)將引發錯誤。 – RobG 2012-07-09 02:53:20

+0

謝謝@RobG,在答案中增加了ES5註釋。 – 2012-07-09 03:05:50

3

首先,你的第二個數組應該是一個對象,而不是有效的JavaScript,作爲前兩個評論者說。這是對象的形式:

var object = { "1": 15, "2": 20, "3": 10, "4": 5, "5": 50 }; 

此功能實現您想要的結果:

function findDiff(arr, obj) 
{ 
    var tempObj = clone(obj); 
    for (var i = 0; i < arr.length; i++) 
    { 
     var propId = arr[i]; 
     if (tempObj[propId] !== undefined) 
      delete tempObj[propId]; 
    } 
    return tempObj; 
} 

此功能依賴於一個名爲clone功能,確保obj被複制到tempObj的價值,而不是參考。這可以防止傳遞的對象被修改:

function clone(obj){ 
    if(obj == null || typeof(obj) != 'object') 
     return obj; 

    var temp = obj.constructor(); // changed 

    for(var key in obj) 
     temp[key] = clone(obj[key]); 
    return temp; 
} 

就這樣稱呼它:

var array = [5, 1, 3]; 
var object = { "1": 15, "2": 20, "3": 10, "4": 5, "5": 50 }; 

var diff = findDiff(array, object); 
+1

請注意,賦值'tempObj = obj'實際上沒有任何用處,該函數返回修改的原始對象,而不是副本。此外,在嘗試刪除屬性名稱之前,應先檢查要刪除的屬性名稱(請參閱[ES5刪除操作符](http://es5.github.com/#x11.4.1)),因爲它可能會在嚴格模式下引發錯誤。 – RobG 2012-07-09 02:35:33

+0

你是對的,很好的捕獲(特別是在我的淺拷貝上,我不知道我是如何錯過的)。編輯我的答案。 – jeff 2012-07-09 02:55:23

2

您需要詳細您所期望的操作的結果是什麼要解釋的。

一種解釋是基於另一個值從一個數組中刪除成員,因此給出:

array1 = [5, 1, 3]; 
array2 = [15, 20, 10, 5, 50 ]; 

你可能有一個功能:

function diff(arr1, arr2) { 
    // Copy arrays so don't affect originals 
    var t1 = arr1.slice(); 
    var t2 = arr2.slice(); 

    // sort t1 
    t1.sort(); 

    // Remove members of arr2 from highest indexes to lowest 
    var i = t1.length; 
    while (i--) { 
    t2.splice(t1[i], 1); 
    } 
    return t2; 
} 

alert(diff(array1, array2)); // 15, 10, 50 

注意,數組是零索引和array2中沒有第5個成員,所以刪除的值是20和5(即分別具有索引1和3的成員)。

0

另一種選擇是,在變量上做一個JSON.stringify()並檢查結果字符串的最左邊或最右邊的字符。如果它是{},那麼您有一個關聯數組/對象,如果[],它是一個數組。根據陣列的大小,我想象的可能會有點貴,但它會完成這項工作。

但是...因爲沒有免費的午餐這樣的東西,所有的動物都是成對的,所以這只是一個合理的解決方案,如果您根據您的原始定義使用了變量。
如果您定義了一個對象,例如:obj = [1,2,3],然後在稍後添加一個值,例如obj['w'] = 'ww',則JSON.stringify(obj)只會生成[1,2,3],但如果再次寫入obj['w'],則仍會得到ww,這意味着該值沒有忘記,他們只是不混合。在內部,我會想象,JavaScript保留兩個單獨的變量表,一個用於對象,另一個用於數組,並且先定義其中的一個,當用stringify打印時獲得點頭。

而且混淆的東西還多,如果你定義一個變量作爲對象,但後來添加的數組鍵,又名

obj = {1: 11, 2: 22, 3: 33}; 
obj[4] = 44; 

新密鑰自動轉換爲字符串,從而產生一個結果字符串的

{"1":11, "2": 22, "3": 33, "4": 44} //sans the \", for better readibility 

混淆爲地獄,但我想這是你付出的一點小無政府狀態和易用性的價格。

相關問題