我有一个数组和一个示例对象,如下所示:
const array = ['a', 'a.b', 'a.b.c', 'a.b.c.d']
样本
const sample = {
'a': 'value',
'b': {
'c': 'value'
},
'c': {
'd': {
'e': 'value'
}
},
'e': {
'f': {
'g': {
'h' : 'value'
}
}
}
}
然后,我想根据数组中的细节修改样本。结果应如下所示:
const newSample = {
'a': 'oldvalue' + 1,
'b': {
'c': 'oldvalue' + 1
},
'c': {
'd': {
'e': 'oldvalue' + 1
}
},
'e': {
'f': {
'g': {
'h' : 'oldvalue' + 1
}
}
}
}
我正在考虑遍历数组并计算每个元素的长度。但是,它的效率不如阵列和样品的水平提高。有没有更好的算法?
const array = ['a', 'b.c', 'c.d.e']
const sample = {
'a': 'value',
'b': {
'c': 'value'
},
'c': {
'd': {
'e': 'value'
}
},
'e': {
'f': {
'g': {
'h' : 'value'
}
}
}
}
const newSample = {}
const transformer = (array) => {
array.forEach(item => {
const itemArr = item.split('.')
if (itemArr.length === 1) {
console.log(sample[itemArr[0]])
newSample[itemArr[0]] = sample[itemArr[0]] + 1
}
// the condition goes on...
})
}
transformer(array)
console.log(newSample)
谢谢,
似乎您只想将新值应用于一组范围域。
您可以在所需的作用域上循环,并为其设置一个新值。以下问题的答案:Convert JavaScript string in dot notation into an object reference对于此问题集非常有效。
const array = ['a', 'c.d.e', 'e.f.g.h'];
const sample = {
'a': 'value',
'b': {
'c': 'someValue'
},
'c': {
'd': {
'e': 'value'
}
},
'e': {
'f': {
'g': {
'h': 'value'
}
}
}
};
const newSample = setValueForKeys(sample, array, 'someValue');
console.log(newSample);
function setValueForKeys(source, keys, value) {
keys.forEach((key) => index(source, key, value));
return source;
}
// See: https://stackoverflow.com/a/6394168/1762224
function index(obj, is, value) {
if (typeof is == 'string') return index(obj, is.split('.'), value);
else if (is.length == 1 && value !== undefined) return obj[is[0]] = value;
else if (is.length == 0) return obj;
else return index(obj[is[0]], is.slice(1), value);
}
function multiIndex(obj, is) {
return is.length ? multiIndex(obj[is[0]], is.slice(1)) : obj;
}
function pathIndex(obj, is) {
return multiIndex(obj, is.split('.'))
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
您可以使用forEach
循环执行此操作,以循环数组中的每个元素,然后循环到split
数组的每个路径,然后对该路径数组使用reduce
方法来更新每个嵌套的属性。
const array = ['a', 'b.c', 'c.d.e']
const sample = {"a":"value","b":{"c":"value"},"c":{"d":{"e":"value"}},"e":{"f":{"g":{"h":"value"}}}}
function update(array, sample) {
array.forEach(c => {
c.split('.').reduce((r, e, i, a) => {
if (!a[i + 1]) r[e] = r[e] + 1
else return r[e] || {}
}, sample)
})
}
update(array, sample);
console.log(sample)
您可以减少分割的键,并用最后一个键保存分配的最后一个键。
const
keys = ['a', 'b.c', 'c.d.e']
object = { a: 'value', b: { c: 'value' }, c: { d: { e: 'value' } }, e: { f: { g: { h : 'value' } } } },
transformer = (objec, keys) => keys.reduce((r, s) => {
var path = s.split('.'),
last = path.pop(),
final = path.reduce((o, k) => o[k] = o[k] || {}, r);
final[last] = (final[last] || '') + 1; // or whatever you need change
return r;
}, object);
console.log(transformer(object, keys));
.as-console-wrapper { max-height: 100% !important; top: 0; }