2012-03-04 32 views
2
var params = { 
    search: { 
     make: "", 
     model: "" 
    } 
} 

function setVariable() { 
    var value = "BMW"; 
    var key = "search.make"; 
    var arr = key.split("."); //eg. ["search", "make"] 
    params[arr[0]][arr[1]] = value; // this works, but how do you 
             // do it with unknown arr[] length? 
} 

如何使用未知的arr[]長度來執行此操作?在javascript中的對象內設置屬性值未知的深度值

我猜測我可能需要做一個遞歸調用,也許在函數中傳遞類似arr.slice(1)的東西,但我一直無法弄清楚應該是什麼樣子。

+2

如果'search'甚至不存在?你想創建對象'{make:value}'然後將它分配給'params.search'?或者你只想設置*現有*屬性的值? – 2012-03-04 11:29:39

回答

2
var params = { 
    search: { 
     make: "", 
     model: "", 
     whatever: { 
      foo: { 
       bar: { 
        moo: 123, 
        meow: 'xyz' 
       } 
      } 
     } 
    } 
}; 

function updatePath(obj, path, value) { 
    var parts = path.split('.'); 
    var i, tmp; 
    for(i = 0; i < parts.length; i++) { 
     tmp = obj[parts[i]]; 
     if(value !== undefined && i == parts.length - 1) { 
      tmp = obj[parts[i]] = value; 
     } 
     else if(tmp === undefined) { 
      tmp = obj[parts[i]] = {}; 
     } 
     obj = tmp; 
    } 
    return obj; 
} 

演示:

> updatePath(params, 'search.whatever.foo.bar') 
{ moo: 123, meow: 'xyz' } 
> updatePath(params, 'search.whatever.foo.bar.moo') 
123 
> updatePath(params, 'search.whatever.foo.bar.moo', 'test') 
'test' 
> updatePath(params, 'search.whatever.foo.bar.moo') 
'test' 
> updatePath(params, 'search.whatever.foo.bar') 
{ moo: 'test', meow: 'xyz' } 
> updatePath(params, 'search.whatever.foo.bar.x.y.z', 'hi') 
'hi' 
> updatePath(params, 'search.whatever.foo.bar.x') 
{ y: { z: 'hi' } } 
> updatePath(params, 'search.whatever.foo.bar') 
{ moo: 'test', 
    meow: 'xyz', 
    x: { y: { z: 'hi' } } } 
> 
2

下面的代碼遍歷您的params對象,直到找到給定的鍵。它假定key.split(".")返回鍵的正確陣列(所以你可能需要在這裏進一步淨化你的輸入

var params = { 
    search: { 
     make: "", 
     model: "" 
    } 
} 

function setVariable() { 
    var value = "BMW"; 
    var key = "search.make"; 
    var arr = key.split("."); //eg. ["search", "make"] 

    var runner = params; 
    for(var i=0, max=arr.length-1; i<max; ++i) { 
     // make sure the key exists 
     runner[ arr[i] ] = runner[ arr[i] ] || {}; 
     // move one level deeper 
     runner = runner[ arr[i] ]; 
    } 

    // set the value in the last level 
    runner[ arr[arr.length-1] ] = value; 
} 

編輯: WRT費利克斯·克林的評論:假定您想以前沒有existant鍵。要產生否則你將不得不把AA進一步檢查到for環和離開的功能,如果該鍵不存在,而不是創建它

+0

這不會設置'runner'變量的值,而不是原始的'params'變量嗎? – alnafie 2012-03-04 11:41:26

+1

因爲它總是工作的ob對象,'runner'和'params'總是分別指向相同的對象或它的一部分。像runner = 3;這樣的表達式會破壞這個連接,但是向對象添加一個新的鍵不會。所以上面的腳本應該爲原始對象添加值。 [也修正錯字] – Sirko 2012-03-04 11:46:14