2010-08-15 47 views
0

對於我需要在這裏得到結論的人來說,我遇到了麻煩,所以請在閱讀之前仔細閱讀並仔細考慮它。使用Javascript在一個對象中定位(un)已知位置

以下是這種情況:

您有一個傳入的對象。你不知道這個對象的結構。然而,你確實有對象的「目標」。因此,讓我們假裝有myObject,你有某種像聯想水平的數組定義目標:

var objectTarget = [ 'firstLevel', 'secondLevel' ,'targetProperty' ]; 

現在進入myObject看起來是這樣的:

{ 
    firstLevel: { 
     secondLevel: { 
      targetProperty: "The goods!" 
     } 
    } 
} 

但正如前面所說的,你不知道結構。您所知道的是objectTarget陣列中的內容。

我的問題是能夠解決基於目標的一個對象內的任意位置。如果我知道的是,目標將總是是三個層次的深度,那麼我可以簡單地引用這樣的:

myObject[objectTarget[1]][objectTarget[2]][objectTarget[3]]; 

但是,因爲我不能確定水平的深度的數量,這是不夠的。我能夠完成此任務的唯一方法是選擇最大數量的合理級別,然後打開它。像這樣:

switch (objectTarget.length) { 
    case 1: 
     var result = myObject[objectTarget[1]]; 
     break; 
    case 2: 
     var result = myObject[objectTarget[1]][objectTarget[2]]; 
     break; 
    case 3: 
     var result = myObject[objectTarget[1]][objectTarget[2]][objectTarget[3]]; 
     break; 
    case 4: 
     var result = myObject[objectTarget[1]][objectTarget[2]][objectTarget[3]][objectTarget[1]]; 
     break; 
} 

...等

這顯然是非常凌亂,而不是最佳的解決方案。

這是否正確地解釋我的問題?有沒有一種更清潔的方式來完成這一點?

非常感謝您提供任何建議。

回答

1

了我的頭頂部的嘗試:

function findTarget(obj, targets) { 
    for(var i = 0; i < targets.length; i++) { 
     var prop = targets[i]; 
     if(obj[prop] != undefined) { 
     obj = obj[prop]; 
     } else { 
     return undefined; // Whatever you want when the target does not exist 

     // or, if it's useful to you 
     return obj; // Maximum reachable target 
     } 
    } 

    return obj; 
} 

var target = findTarget(incoming, ['level1', 'level2', ...]); 

if(target == undefined) { 
    // couldn't traverse the entire target list... 
} 
+0

謝謝!問題:你猜這是多慢? – Spot 2010-08-15 05:54:42

+1

我不認爲這比你提前知道路徑慢得多。在'obj.leve1.level2.target'這樣的東西中每個''''都需要一個運行時查找,所以你不會從預知中獲得任何東西。儘管對於遍歷的每個深度,您都需要額外的訪問權限才能使用此方法獲得目標的名稱('targets [i]'部分)。我不會擔心此代碼的速度,除非目標。長度'變大。 – 2010-08-15 06:03:17

1

另一種方法,如果你可以使用(或包括IE)的reduce陣列方法:

function getTarget(obj, target) { 
    return target.reduce(function(a, b) { return a && a[b]; }, obj); 
} 

// usage (assuming that `myObject` is your sample object): 
var target = ['firstLevel', 'secondLevel' ,'targetProperty']; 
getTarget(myObject, target); // "The goods!"