提问人:noname028743 提问时间:8/16/2023 最后编辑:noname028743 更新时间:8/16/2023 访问量:32
使用某些数组对对象进行深度搜索的问题
Problem with Depth Search of object with some arrays
问:
我使用此脚本在对象中进行深度搜索。我使用字符串来获取或设置对象中的值。我认为代码可以解释一切:
function _SetObjectByName(obj, prop, value) {
try {
if (typeof obj === 'undefined') {
return false;
}
let _index = prop.indexOf('.');
if (_index > -1) {
let _NestedObject = prop.substring(0, _index);
let _newProp = prop.substr(_index + 1);
if (_NestedObject.includes('[')) {
let ArrayElement = _NestedObject.match(/\d+/)[0];
_NestedObject = _NestedObject.substring(0, _NestedObject.indexOf('['));
return _SetObjectByName(obj[_NestedObject][parseInt(ArrayElement, 10)], _newProp, value);
}
return _SetObjectByName(obj[_NestedObject], _newProp, value);
}
obj[prop] = value;
}
catch(err) {
console.log('error');
}
}
我的对象:
let Object5 = {
Bool: false,
Number1: 0,
Number2: 0,
Number3: 0,
Number4: 0,
Number5: 0,
Number6: 0,
Number7: 0
};
let Object4 = {
Text: '',
ObjectA: Object.assign({}, Object5),
ObjectB: Object.assign({}, Object5),
ObjectC: Object.assign({}, Object5),
ObjectD: Object.assign({}, Object5),
};
let Object3 = {
Text: '',
ObjectA: [ Object.assign({}, Object4),
Object.assign({}, Object4)
]
};
let Object2 = {
Text: '',
ObjectA: [ Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3)
]
};
let Object1 = {
Text: '',
ObjectA: [ Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2)
]
};
所以现在如果我试试这个:
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[0].Text','Test1')
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[1].Text','Test2')
它按预期工作 - >不同的值,但如果这样做:
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[0].ObjectA.Number1',1)
我有一个问题。ObjectA[0] 的所有数组元素。对象 A[0]。对象 A[X]。ObjectA.Number1 为 1。 有人可以解释我为什么吗?
答:
0赞
Alexander Nenashev
8/16/2023
#1
只需生成一个函数即可为 obj 中的任何路径分配一个值。
function _SetObjectByName(obj, path, value){
const fn = new Function('obj, path, value', `obj.${path} = ${JSON.stringify(value)}`);
fn(obj, path, value);
}
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[0].Text','Test1')
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[1].Text','Test2')
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[0].ObjectA.Number1',1)
$result.textContent = JSON.stringify(Object1, null, 4);
<pre id="$result"></pre>
<script>
let Object5 = {
Bool: false,
Nummer1: 0,
Nummer2: 0,
Nummer3: 0,
Nummer4: 0,
Nummer5: 0,
Nummer6: 0,
Nummer7: 0
};
let Object4 = {
Text: '',
ObjectA: Object.assign({}, Object5),
ObjectB: Object.assign({}, Object5),
ObjectC: Object.assign({}, Object5),
ObjectD: Object.assign({}, Object5),
};
let Object3 = {
Text: '',
ObjectA: [ Object.assign({}, Object4),
Object.assign({}, Object4)
]
};
let Object2 = {
Text: '',
ObjectA: [ Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3)
]
};
let Object1 = {
Text: '',
ObjectA: [ Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2)
]
};
</script>
另请注意,您在多个位置具有相同的对象,因此更改其中的值会更改所有对象引用中的值。
Object.assign()
无济于事,因为您有对象属性,它只对标量属性有帮助。
如果你用它做一个克隆,你会像你想要的那样工作:JSON.stringify()
function _SetObjectByName(obj, path, value){
const fn = new Function('obj, path, value', `obj.${path} = ${JSON.stringify(value)}`);
fn(obj, path, value);
}
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[0].Text','Test1')
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[1].Text','Test2')
_SetObjectByName(Object1,'ObjectA[0].ObjectA[0].ObjectA[0].ObjectA.Number1',1)
$result.textContent = JSON.stringify(Object1, null, 4);
<pre id="$result"></pre>
<script>
let Object5 = {
Bool: false,
Nummer1: 0,
Nummer2: 0,
Nummer3: 0,
Nummer4: 0,
Nummer5: 0,
Nummer6: 0,
Nummer7: 0
};
let Object4 = {
Text: '',
ObjectA: Object.assign({}, Object5),
ObjectB: Object.assign({}, Object5),
ObjectC: Object.assign({}, Object5),
ObjectD: Object.assign({}, Object5),
};
let Object3 = {
Text: '',
ObjectA: [ Object.assign({}, Object4),
Object.assign({}, Object4)
]
};
let Object2 = {
Text: '',
ObjectA: [ Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3),
Object.assign({}, Object3)
]
};
let Object1 = JSON.parse(JSON.stringify({
Text: '',
ObjectA: [ Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2),
Object.assign({}, Object2)
]
}));
</script>
评论
0赞
noname028743
8/16/2023
感谢您的支持。我看到有更简单的方法可以访问带有字符串的对象。在对象中复制对象的正确方法是什么?有些对象会随着时间而变化,我想以最简单的方式进行编辑。
0赞
Alexander Nenashev
8/16/2023
@noname028743第二个代码片段显示了如何使用 深度克隆对象。你也可以使用JSON.stringify()
structuredClone()
0赞
noname028743
8/16/2023
function _GetObjectByName(obj, path) { const fn = new Function('obj, path', ); return fn(obj, path); } 返回对象。return obj.${path}
0赞
Alexander Nenashev
8/16/2023
@noname028743,是的,也有可能。并修改其属性
0赞
noname028743
8/17/2023
你能推荐一些东西来比较两个对象吗?它应该被称为深度对象搜索。我尝试了 Lodash,但我总是只得到第一级作为返回值。我也可以开始一个新问题,但我认为你是一个非常聪明的人;)
评论