使用某些数组对对象进行深度搜索的问题

Problem with Depth Search of object with some arrays

提问人:noname028743 提问时间:8/16/2023 最后编辑:noname028743 更新时间:8/16/2023 访问量:32

问:

我使用此脚本在对象中进行深度搜索。我使用字符串来获取或设置对象中的值。我认为代码可以解释一切:

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。 有人可以解释我为什么吗?

JavaScript HTML 数组 对象

评论

0赞 GreenChicken 8/16/2023
我运行了 Number1 案例的脚本,然后我刚刚将另一个 Number1(值为 1)添加到 Object4 中......所以我的行为与你不同,我不知道为什么

答:

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,但我总是只得到第一级作为返回值。我也可以开始一个新问题,但我认为你是一个非常聪明的人;)