2016-09-16 59 views
3

陣列的路上我不知道是否有一個簡單的方法來完成在JavaScript推值轉換成在JavaScript

以下

,我已經有了代碼:

var formattedObject = { 
    "id": "1" 
}; 
var mapping = { 
    "name": "name", 
    "project": "projects.0.name" 
}; 
$.each(mapping, function(path, fieldName) { 
    fieldValue = $('form input[name="' + fieldName + '"]').val(); 
    /* 
     Here I need to push a field value into array by path 
    */ 
}); 

我希望我的格式化什麼對象看起來像:

var formattedObject = { 
    "id": "1", 
    "name": "Object name", //comes from input field 
    "projects": [{ 
     "name": "My project name" //comes from input field 
    }] 
}; 

而問題:有沒有一種簡單的方法來設置formattedObject的值由路徑?

我的計劃是通過「。」拆分路徑,循環遍歷它並在formattedObject內創建所需的層次結構。但想知道是否有更好的方法來做到這一點?

+0

順便說一句,它不需要具有該類型的路徑「projects.0.name」(帶點「。」)。它可以是其他一些符號,如果這使得它更容易... – AndVla

回答

1

通過利用Object.prototype.setNestedValue()可以動態地設置一個深度嵌套對象的任何值。您所需要的只是在參數中以正確的順序提供屬性名稱和數組索引。最後一個參數是要設置的值。

讓我們來看看...

Object.prototype.setNestedValue = function(...a) { 
 
    a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1)) 
 
                     : (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]), 
 
                     this[a[0]].setNestedValue(...a.slice(1))) 
 
       : this[a[0]] = a[1]; 
 
    return this; 
 
}; 
 

 
var formattedObject = { 
 
    "id": "1", 
 
    "name": "Object name", //comes from input field 
 
    "projects": [{ 
 
     "name": "My project name" //comes from input field 
 
    }] 
 
}; 
 

 
console.log(JSON.stringify(formattedObject.setNestedValue("name","New Name"),null,4)); 
 
console.log(JSON.stringify(formattedObject.setNestedValue("projects",0,"name","New Project Name"),null,4));

你可能當然選擇Object.prototype.setNestedValue()轉換成正常的功能,並相應地調整你的代碼。

2

您可以拆分路徑並檢查以下元素是否存在。如果不檢查以下元素的編號並分配一個數組,否則將一個對象分配給新的屬性。然後返回屬性的值。

最後賦值。

function setValue(object, path, value) { 
 
    var fullPath = path.split('.'), 
 
     way = fullPath.slice(), 
 
     last = way.pop(); 
 

 
    way.reduce(function (r, a, i, aa) { 
 
     function isNumber(v) { 
 
      return String(+v) === v; 
 
     } 
 
     return r[a] = r[a] || isNumber(fullPath[i + 1]) ? [] : {}; 
 
    }, object)[last] = value; 
 
} 
 

 
var formattedObject = { 
 
     id: "1" 
 
    }, 
 
    mapping = { 
 
     name: "name", 
 
     project: "projects.0.name" 
 
    }; 
 

 
setValue(formattedObject, mapping.name, 'xyz'); 
 
setValue(formattedObject, mapping.project, 42); 
 

 
console.log(formattedObject);