2015-09-25 27 views
13

Tôi muốn thực hiện một chức năng gọi là createAssociativeArray mà sẽ recive hai tham số: stringobject, như thế này:Tạo một cấu trúc lồng nhau đối tượng bằng chuỗi chìa khóa/path

function createAssociativeArray(string, object) { 
    //... 
} 

Mục cuối cùng của string sẽ nhận được object dữ liệu. Xem ví dụ về sử dụng/trả lại:

createAssociativeArray('key1.key2.key3', { 
    data1: 1, 
    data2: 2, 
    data3: 3 
}); 

// key1: { 
// key2: { 
//  key3: { 
//  data1: 1, 
//  data2: 2, 
//  data3: 3 
//  } 
// } 
// } 

Phương pháp đơn giản và mạnh mẽ nhất để làm điều đó là gì?

Sử dụng eval không phải là một khả năng.


Những gì tôi đã cố gắng:

function createAssociativeArray(string, object) { 
    string = string.split('.'); 
    return string.reduce(function(_object, _target, i) { 
    _object[_target] = (i + 1 === string.length ? object : {}); 
    return _object; 
    }, {}); 
} 

Nó không tạo ra kết quả mong đợi vì các đối tượng được reseted để {}.

[JSFiddle]

+1

Bạn đang cố gắng triển khai các không gian tên? Ngoài ra, biến 'i' đến từ đâu? –

+0

@StefanBaiu, một cái gì đó như ... Đó là một 'chỉ số' từ' giảm' (cập nhật). –

Trả lời

5

Đây là những gì tôi đã đưa ra:

function createAssociativeArray(string, object) { 
    var parts = string.split('.'); 
    var last = parts[parts.length - 1]; 
    var tree = {}; 

    var node = parts.slice(0, -1).reduce(function (memo, current) { 
    return (memo[current] = {}); 
    }, tree); 

    node[last] = object; 
    return tree; 
} 
+0

Hãy thử điều này nếu bạn muốn kết hợp với một đối tượng thoát (đặt giá trị trên một đường dẫn JSON trong một đối tượng nhất định): http://stackoverflow.com/a/32791758/2045312 – TechMaze

3

Tôi đã tò mò muốn xem liệu tôi có thể làm cho một giải pháp đệ quy, vì vậy ở đây là:

function createAssociativeArray(string, object) { 
    if (string === "") return object; 
    var stringarr = string.split('.'); 
    var laststr = stringarr.pop(); 
    var newobj = {}; 
    newobj[laststr] = object; 
    return createAssociativeArray(stringarr.join("."), newobj); 
} 

Bản trình diễn JSFiddle đang hoạt động: https://jsfiddle.net/pt352dxg/

2

Có thể triển khai vào lúc:

Working demo

function createChain(keys, value) { 
    var obj = {}; 
    var target = obj; 
    keys = keys.split('.'); 
    keys.forEach(function(key, index) { 
    target = target[key] = index === keys.length - 1 ? value : {}; 
    }); 
    target = value; 
    return obj; 
} 
2

Chức năng này thực sự có thể chấp nhận một đối tượng hiện có tùy chọn ({k: 2, kk: 3, key1: 4}) và hợp nhất rằng với con đường json nhất định. ví dụ. Thử gỡ rối chrome console:

JSON.stringify(createAssociativeArray('key1.key2.key3', { data1: 1, data2: 2, data3: 3}, {k:2,kk:3, key1:{}})) 

sẽ in này:

"{"k":2,"kk":3,"key1":{"key2":{"key3":{"data1":1,"data2":2,"data3":3}}}}" 

..

function createAssociativeArray(key, value, data) { 
     if(!finalData && data) 
      finalData = data; 
     var finalData; 
     if (!data) 
      data = finalData = {}; 
     var keys = key.split('.'); 
     if (keys.length < 2) { 
      data[keys[0]] = value; 
     } else { 
      if (!data[keys[0]]) 
       data[keys[0]] = {}; 
      data = data[keys.shift()];    
      createAssociativeArray(keys.join("."),value,data); 
     } 
     return finalData; 
    }; 
1

này đã làm việc cho tôi:

function createAssociativeArray(string, object){ 
    var array = string.split('.'); 
    var aArray = {}; 
    if(array.length > 1){ 
     aArray[array[array.length - 1]] = object; 
     array.splice(array.length - 1, 1); 
     createAssociativeArray(array.join('.'), aArray) 
    }else{ 
     aArray[array[array.length - 1]] = object; 
     return aArray 
    } 
}; 


createAssociativeArray('key1.key2.key3', {data1: 1, data2: 2, data3: 3}); 

Về cơ bản, xây dựng đối tượng từ nối đất, bắt đầu với objec gốc t, sau đó gói 'các lớp' xung quanh nó một cách đệ quy

1

Trường hợp đẹp cho chức năng đệ quy!

function createAssociativeArray(string, object) { 
    if (string.split('.').length == 1) { 
    var outObj = {}; 
    outObj[string] = object; 
    return outObj; 
    } else { 
    var outObj = {}; 
    outObj[string.split('.')[0]] = createAssociativeArray(string.split('.').slice(1).join('.'), object); 
    return outObj; 
    } 
} 
2

Bạn đã gần hoàn toàn trong nỗ lực ban đầu của mình.

function createAssociativeArray(string, object) { 
    return string.split('.').reverse().reduce(function (inner, key) { 
     var outer = {}; 
     outer[key] = inner; 
     return outer; 
    }, object); 
} 

http://jsfiddle.net/xewoa06t/

0

Nó dễ dàng hơn với một vòng lặp đơn giản, điểm mấu chốt là làm ngược lại (như @JustcallmeDrago)

function createAssociativeArray(keys, data) 
 
{ 
 
    var temp, keyPart 
 
    
 
    for(keys = keys.split('.'); keys.length; data = temp) 
 
    { 
 
    keyPart = keys.pop() 
 
    temp = {} 
 
    temp[keyPart] = data 
 
    } 
 
    return data 
 
} 
 

 
// TEST 
 

 
x = createAssociativeArray("key1.key2.key3", { data1: "value1", data2: "value2" }) 
 

 
document.write('<pre>'+x+'\n'+x.key1 +'\n' 
 
       +x.key1.key2 + '\n' 
 
       +x.key1.key2.key3 +'\n' 
 
       +x.key1.key2.key3.data1 +'\n' 
 
       +x.key1.key2.key3.data2 +'</pre>')

0

Kể từ khi không có ai đã proviced một while giải pháp -lớp:

function namespace(path, context) { 
    var obj = context; 
    var s = path.split('.'); 
    var p; 
    while (s.length) { 
     p = s.shift(); 
     obj = obj[p] || (obj[p] = {}); 
    } 
    return context; 
} 
Các vấn đề liên quan