使用reduce压平数组后更改特定对象值,如何操作?

问题描述 投票:0回答:1

我有一个嵌套的对象数组,它可以深入多个级别。出于其他目的,我必须将对象数组展平为 1 级(非嵌套)数组。 当我只知道 id 时,如何更新 1 个特定对象?

这是对象数组的示例:

let items = [
  {
    id: 2,
    test: false,
    items: []
  },
  {
    id: 3,
    test: false,
    items: [
      {
        id: 4,
        test: false,
        items: [
          {
            id: 10,
            test: false,
            items: []
          },
        ]
      },
    ]
  },
  {
    id: 1,
    test: false,
    items: []
  },
];

我在这个线程中使用了这种展平方法:递归地深度展平 JavaScript 对象

function flatten(xs) {
  return xs.reduce((acc, x) => {
    acc = acc.concat(x);
    if (x.items) {
      acc = acc.concat(flatten(x.items));
      x.items = [];
    }
    return acc;
  }, []);
}

假设我想将 test 更新为 true,仅在 id 10 中。在原始数组上执行此操作的最简单方法是什么?当我更新展平数组对象时,引用不再链接到原始数组。

javascript arrays object reference reduce
1个回答
0
投票

由于您的对象具有硬结构,您可以递归地迭代它们的项目并找到您的目标对象:

const findObject = (items, id) => {
  for(const item of items){
    if(item.id === id){
      return item;
    }
    if(item.items.length){
      const found = findObject(item.items, id);
      if(found) return found;
    }
  }
  return null;
};

const found = findObject(items, 10)
found.test = true;

console.log(items);
<script>
let items = [
  {
    id: 2,
    test: false,
    items: []
  },
  {
    id: 3,
    test: false,
    items: [
      {
        id: 4,
        test: false,
        items: [
          {
            id: 10,
            test: false,
            items: []
          },
        ]
      },
    ]
  },
  {
    id: 1,
    test: false,
    items: []
  },
];
</script>

更高级的代码将具有遍历树并更新项目的功能。例如,在这里我们更新 id 为 3 的 item 的所有后代,并将它们的

test
设置为
true
:

const transformTree = (items, filterCb, updateCb, parents = []) => {
  for(const item of items){
    if(filterCb(item, parents)){
      if(false === updateCb(item, parents)){
        return false;
      }
    }
    if(item.items.length){
      if(false === transformTree(item.items, filterCb, updateCb, parents.concat(item))){
        return false;
      }
    }
  }
};

transformTree(items, (item, parents) => parents.some(parent => parent.id === 3), item => item.test = true);

console.log(items);
<script>
let items = [
  {
    id: 2,
    test: false,
    items: []
  },
  {
    id: 3,
    test: false,
    items: [
      {
        id: 4,
        test: false,
        items: [
          {
            id: 10,
            test: false,
            items: []
          },
        ]
      },
    ]
  },
  {
    id: 1,
    test: false,
    items: []
  },
];
</script>

© www.soinside.com 2019 - 2024. All rights reserved.