遍历嵌套对象并修改特定属性

时间:2021-01-07 15:15:59

标签: javascript arrays nested

我有一个嵌套的对象,如下所示:

我想要的只是一个递归函数,它遍历这个对象并为 'id' 属性分配一个随机值。

 let data = [{ id: 1, name: '', children: [{ id: 11, name: '', children: [] }, { id: 12, name: '', children: [{ id: 121, name: '', children: [] }, { id: 122, name: '', children: [] }] } ] }, { id: 2, name: '', children: [{ id: 21, name: '', children: [] }, { id: 22, name: '', children: [{ id: 221, name: '', children: [] }, { id: 222, name: '', children: [] }] } ] } ];

这是我试过的代码,我已经修复了

const cloneNodesWithNewIds = (tree) => {
  const result = tree.map((elem) =>
    elem.children ? {
      ...elem,
      id: Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1),
      children: cloneNodesWithNewIds(elem.children),
    } :
    elem
  );
  return result;
}

console.log(cloneNodesWithNewIds(data))

谢谢各位

4 个答案:

答案 0 :(得分:1)

这样的事情应该做你想做的

let data = [{ id: 1, name: '', children: [{ id: 11, name: '', children: [] }, { id: 12, name: '', children: [{ id: 121, name: '', children: [] }, { id: 122, name: '', children: [] }] } ] }, { id: 2, name: '', children: [{ id: 21, name: '', children: [] }, { id: 22, name: '', children: [{ id: 221, name: '', children: [] }, { id: 222, name: '', children: [] }] } ] } ];

function recursiveEdition(object, label, value) {
    // If we the object is not an object, there is nothing to do
    if (typeof object !== 'object') {
      return;
    }

    // We check every attribute of the object
    Object.keys(object).forEach((index) => {
        if (index === label) {
            // If it is the desired index, we change the value
            object[index] = value;
        } else {
            if it is not the desired index, we continue the navigation
            recursiveEdition(object[index], label, value);
        } 
    });

    return object
}

答案 1 :(得分:1)

也许这样更快

let data = [{ id: 1, name: '', children: [{ id: 11, name: '', children: [] }, { id: 12, name: '', children: [{ id: 121, name: '', children: [] }, { id: 122, name: '', children: [] }] } ] }, { id: 2, name: '', children: [{ id: 21, name: '', children: [] }, { id: 22, name: '', children: [{ id: 221, name: '', children: [] }, { id: 222, name: '', children: [] }] } ] } ];

const maxVal = 300;
let rndArr = []
const getRdn = () => { let rnd = Math.ceil(Math.random()*maxVal); while (rndArr.includes(rnd)) rnd = Math.ceil(Math.random()*maxVal); rndArr.push(rnd); return rnd; }; // unique. Can be simplified if not needed

data = JSON.parse(
  JSON.stringify(data)
    .replace(/"id":\d+/g, match => `"id":${getRdn()}`)
)
console.log(data)

答案 2 :(得分:0)

下面是递归方法。如果obj类型的阵列然后在调用forEach

const random = () => Math.floor(Math.random() * 1000)

const updateAttr = (item) => {
  if (Array.isArray(item)) {
    item.forEach(updateAttr);
  } else {
    item.id = random();
    updateAttr(item.children); 
  }
}  

const data = [
  {
    id: 1,
    name: "",
    children: [
      {
        id: 11,
        name: "",
        children: [],
      },
      {
        id: 12,
        name: "",
        children: [
          {
            id: 121,
            name: "",
            children: [],
          },
          {
            id: 122,
            name: "",
            children: [],
          },
        ],
      },
    ],
  },
  {
    id: 2,
    name: "",
    children: [
      {
        id: 21,
        name: "",
        children: [],
      },
      {
        id: 22,
        name: "",
        children: [
          {
            id: 221,
            name: "",
            children: [],
          },
          {
            id: 222,
            name: "",
            children: [],
          },
        ],
      },
    ],
  },
];

updateAttr(data);

console.log(data)

答案 3 :(得分:0)

这是一个使用 object-scan 的迭代版本。它相对干净,但它确实引入了依赖项,因此需要权衡。

// const objectScan = require('object-scan');

const myData = [{ id: 1, name: '', children: [{ id: 11, name: '', children: [] }, { id: 12, name: '', children: [{ id: 121, name: '', children: [] }, { id: 122, name: '', children: [] }] }] }, { id: 2, name: '', children: [{ id: 21, name: '', children: [] }, { id: 22, name: '', children: [{ id: 221, name: '', children: [] }, { id: 222, name: '', children: [] }] }] }];
const myPRNG = (value) => Math.abs(Math.floor(Math.sin(value) * 1000));

const modify = (data, rng) => objectScan(['**.id'], {
  rtn: 'count',
  filterFn: ({ parent, property, value }) => {
    parent[property] = rng(value);
  }
})(data);

console.log(modify(myData, myPRNG));
// => 10

console.log(myData);
// => [ { id: 841, name: '', children: [ { id: 1000, name: '', children: [] }, { id: 537, name: '', children: [ { id: 998, name: '', children: [] }, { id: 498, name: '', children: [] } ] } ] }, { id: 909, name: '', children: [ { id: 836, name: '', children: [] }, { id: 9, name: '', children: [ { id: 885, name: '', children: [] }, { id: 868, name: '', children: [] } ] } ] } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.7.1"></script>

免责声明:我是object-scan

的作者
相关问题