Javascript 创建点外对象表示法
这是一个与之相反的问题 给定一个对象Javascript 创建点外对象表示法,javascript,json,Javascript,Json,这是一个与之相反的问题 给定一个对象x={a:1,b:2}和一个字符串c.d=3,将对象x修改为以下内容: { 答:1,, b:2, c:{ d:3 } } 我正在寻找一种不使用eval的解决方案。用例如下所示: x作为一个配置对象,我们称之为: config.set(“music.shuffle”,true) 现在,必须以某种方式解析music.shuffle,并将其添加到config.set函数中的内部对象x,使x看起来像: x={a:1,b:2,音乐:{shuffle:true} 我想你
x={a:1,b:2}
和一个字符串c.d=3
,将对象x修改为以下内容:
{
答:1,,
b:2,
c:{
d:3
}
}
我正在寻找一种不使用eval
的解决方案。用例如下所示:
x
作为一个配置对象,我们称之为:
config.set(“music.shuffle”,true)
现在,必须以某种方式解析music.shuffle
,并将其添加到config.set函数中的内部对象x
,使x看起来像:
x={a:1,b:2,音乐:{shuffle:true}
我想你可以这样做:
function addValueToObj(obj, newProp) {
newProp = newProp.split("="); // separate the "path" from the "value"
var path = newProp[0].split("."), // separate each step in the "path"
val = newProp.slice(1).join("="); // allow for "=" in "value"
for (var i = 0, tmp = obj; i < path.length - 1; i++) {
tmp = tmp[path[i]] = {}; // loop through each part of the path adding to obj
}
tmp[path[i]] = val; // at the end of the chain add the value in
}
var x = {a:1, b:2};
addValueToObj(x, "c.d=3");
// x is now {"a":1,"b":2,"c":{"d":"3"}}
addValueToObj(x, "e.f.g.h=9=9");
// x is now {"a":1,"b":2,"c":{"d":"3"},"e":{"f":{"g":{"h":"9=9"}}}}
函数addValueToObj(obj,newProp){
newProp=newProp.split(=”;//将“路径”与“值”分开
var path=newProp[0]。拆分(“.”,//在“路径”中分隔每个步骤
val=newProp.slice(1).join(“=”;//允许在“值”中使用“=”)
对于(var i=0,tmp=obj;i
演示:我相信dojo的setObject可以满足您的需求。如果您(可以理解)不想全部使用dojo,那么我建议您检查它们(免费提供)的源代码,或者通过AMD只加载base(仅4k)。它看起来像这样:
function setObject(name, value, context) {
var parts=name.split("."),
p=parts.pop();
for(var i=0, j; context && (j=parts[i]); i++){
context = (j in context ? context[j] : context[j]={});
}
return context && p ? (context[p]=value) : undefined; // Object
}
因此,在您的情况下,您会:
x={a:1,b:2};
setObject("c.d", 3, x);
警告:除非您只处理琐碎的情况,否则我建议您还是去查看完整的dojo实现,它处理没有提供上下文的情况等。这里有一个注释较多的版本,应该比较容易理解
// stores the configured data
configStore = {};
config = {
set: function(keyValueString) {
// Split the string by the =
var pair = keyValueString.split('=');
// left of the = is the key path
var keyPath = pair[0];
// right of the = is the value to set
var value = pair[1];
// split keyPath into an array of keys
var keys = keyPath.split('.');
var key; // used in loop
// the current level of object we are drilling into.
// Starts as the main root config object.
var currentObj = configStore;
// Loop through all keys in the key path, except the last one (note the -1).
// This creates the object structure implied by the key path.
// We want to do something different on the last iteration.
for (var i=0; i < keys.length-1; i++) {
// Get the current key we are looping
key = keys[i];
// If the requested level on the current object doesn't exist,
// make a blank object.
if (typeof currentObj[key] === 'undefined') {
currentObj[key] = {};
}
// Set the current object to the next level of the keypath,
// allowing us to drill in.
currentObj = currentObj[key];
}
// Our loop doesn't handle the last key, because that's when we
// want to set the actual value. So find the last key in the path.
var lastKey = keys[keys.length-1]
// Set the property of the deepest object to the value.
currentObj[lastKey] = value;
}
};
// Do it.
config.set('omg.wtf.bbq=123')
// Check it.
alert(configStore.omg.wtf.bbq); // 123
//存储配置的数据
configStore={};
配置={
设置:函数(keyValueString){
//将字符串按顺序拆分=
var pair=keyValueString.split('=');
//=的左侧是关键路径
var keyPath=pair[0];
//=右侧是要设置的值
var值=对[1];
//将keyPath拆分为一组密钥
var keys=keyPath.split('.');
var key;//在循环中使用
//我们正在钻取的对象的当前级别。
//作为主根配置对象启动。
var currentObj=配置存储;
//循环键路径中的所有键,最后一个键除外(注意-1)。
//这将创建键路径隐含的对象结构。
//我们希望在最后一次迭代中做一些不同的事情。
对于(变量i=0;i
今天不得不做类似的事情,这里有另一个解决方案。当然可以进行一些清理,但它确实做到了。这将扩展现有对象,并且如果输入有效,则不会擦除任何数据
没有验证,所以如果传递错误数据,您肯定可以覆盖密钥
// @param object orig the object to extend
// @param array keyParts the.key.path split by "." (expects an array, presplit)
// @param mixed value the value to assign
// @param object scoped used by the recursion, ignore or pass null
function unflatten(orig, keyParts, value, scoped) {
if (!scoped) {
scoped = orig;
}
var nextKey = keyParts.shift();
if (keyParts.length === 0) {
scoped[nextKey] = value;
return orig;
}
if (!scoped[nextKey]) {
scoped[nextKey] = {};
}
scoped = scoped[nextKey];
return unflatten(orig, keyParts, value, scoped);
}
功能原型可以改进,但满足我的需要。电话:
var orig = { foo: 'hello world', bar: { baz: 'goodbye world' } };
// lets add the key "bar.cat.aww" with value "meow"
unflatten(orig, "bar.cat.aww".split("."), "meow");
/*
orig is {
foo: "hello world",
bar: {
baz: "goodbye world",
cat: {
aww: "meow"
}
}
}
*/
// we can keep calling it to add more keys
unflatten(orig, "some.nested.key".split("."), "weeee");
/*
orig is {
foo: "hello world",
bar: {
baz: "goodbye world",
cat: {
aww: "meow"
}
},
some: {
nested: {
key: "weeee"
}
}
}
*/
你可以用它来做这个
>l=要求('lodash'))
>x={a:1,b:2};
{a:1,b:2}
>l.组(x,'c.d',3)
{a:1,b:2,c:{d:3}
这个怎么样
它将创建或复制/覆盖现有对象
function expando(obj, base) {
return Object.keys(obj)
.reduce((clone, key) => {
key.split('.').reduce((innerObj, innerKey, i, arr) =>
innerObj[innerKey] = (i+1 === arr.length) ? obj[key] : innerObj[innerKey] || {}, clone)
return clone;
}, Object.assign({}, base));
}
console.log(expando({'a.b': 1})) // { a: { b : 1 }}
console.log(expando({'b.c': 2}, { a: 1 })) // { a: 1, b: { c: 2 }}
console.log(expando({'b.c.d': 2, 'e.f': 3}, { a: 1 })) // { a: 1, b: { c: { d: 2 } }, e: { f: 3}}
注意:箭头函数和Object.assign()
需要ES6
尽情玩玩:
这个怎么样:
function setObj (str, value, obj) {
var ref = obj, keys = str.split('.');
while (keys.length) {
var currentKey = keys.shift();
ref[currentKey] = keys.length ? (ref[currentKey] ? ref[currentKey] : {}) : value;
ref = ref[currentKey];
}
}
输入对象使用的示例(可以是使用$.serializeArray提取的一些表单值)
结果
{
"fruits": {
"1": {
"name": "Banana",
"id": "1"
},
"2": {
"name": "Strawberry",
"id": "2"
},
"3": {
"name": "Raspberry",
"id": "3"
},
"4": {
"name": "Kiwi",
"id": "4"
},
"5": {
"name": "Mango",
"id": "5"
}
},
"selected_fruit_id": "1"
}
如果C是一个字符串,那么您必须尝试手动将其解析为一个对象。我几乎可以保证,在创建字符串C的地方,这样做会更容易,而且不必进行任何手动解析。请显示代码的这一部分,以便我可以帮助您进一步了解字符串是否保证为
dot.separated.string=value
,以及对该值有哪些限制?例如,它是JSON类型吗?字符串被保证为dot.separated,并且对值没有任何限制。当然,由询问者决定,但我建议进行更新,这样您就不会破坏已经存在的属性。e、 例如,如果x={a:{b:3}},我做addValueToObj(x,“a.c=4”),那么b消失了。
var serializedInputs = [
{name: 'fruits[1][name]', value: 'Banana'},
{name: 'fruits[1][id]', value: '1'},
{name: 'fruits[2][name]', value: 'Strawberry'},
{name: 'fruits[2][id]', value: '2'},
{name: 'fruits[3][name]', value: 'Raspberry'},
{name: 'fruits[3][id]', value: '3'},
{name: 'fruits[4][name]', value: 'Kiwi'},
{name: 'fruits[4][id]', value: '4'},
{name: 'fruits[5][name]', value: 'Mango'},
{name: 'fruits[5][id]', value: '5'},
{name: 'selected_fruit_id', value: '1'},
]
// This variable holds the result
var obj = {}
serializedInputs.forEach(function(item) {
// Turning square brackets into dot notation
setObj(item.name.replace(/\]/g, '').replace(/\[/g, '.'), item.value, obj);
})
{
"fruits": {
"1": {
"name": "Banana",
"id": "1"
},
"2": {
"name": "Strawberry",
"id": "2"
},
"3": {
"name": "Raspberry",
"id": "3"
},
"4": {
"name": "Kiwi",
"id": "4"
},
"5": {
"name": "Mango",
"id": "5"
}
},
"selected_fruit_id": "1"
}