如果在 JavaScript 中递归搜索时匹配,如何更新对象数组

how to update array of objects if it matches while recursively search in JavaScript

我想在递归搜索找到特定节点后用值更新对象。

我需要在哪里添加逻辑来实现这个?

我想从嵌套的对象数组中获取第一个找到的对象,并根据迭代使用 selected:true 更新数据以获得值 showTree: true

函数:

let findDeep = function(data, label) {
  return data.filter(function(e) {
    if (e.label.includes(label)) {
      data.map(el=> el.selected= "true"); // logic to select the first found value
      return e;
    } 
    else if (e.item) 
    //logic for showTree: true
    return findDeep(e.item, label);
  });
};

数据:

let testData = [
  {
    id: 1,
    label: 'parent1',
    item: [
      {
        id: 21,
        label: 'child1',
        item: [
          {
            id: 211,
            label: 'child31',
            item: [
              {
                id: 2111,
                label: 'child2211',
                item: [
                  {
                    id: 21111,
                    label: 'child22111'
                  }
                ]
              }
            ]
          },
          {
            id: 222,
            label: 'child32'
          }
        ]
      },
      {
        id: 22,
        label: 'child2',
        item: [
          {
            id: 221,
            label: 'child421',
            item: [
              {
                id: 2211,
                label: 'child2211'
              }
            ]
          },
          {
            id: 222,
            label: 'child222'
          }
        ]
      }
    ]
  },
  {
    id: 2,
    label: 'parent2',
    item: [
      {
        id: 21,
        label: 'child2',
        item: [
          {
            id: 511,
            label: 'child51',
            item: [
              {
                id: 5111,
                label: 'child5211',
                item: [
                  {
                    id: 51111,
                    label: 'child52111'
                  }
                ]
              }
            ]
          },
          {
            id: 522,
            label: 'child352'
          }
        ]
      }
    ]
  }
];

我想在输出中有所收获

console.log(findDeep(testData, 'child3')[0]);

//output list
[
   {
      "id":1,
      "label":"parent1",
      "showTree": true,
      "item":[
         {
            "id":21,
            "label":"child1",
            "showTree": true,
            "item":[
               {
                  "id":211,
                  "label":"child31",
                  "selected" true,
                  "item":[
                     {
                        "id":2111,
                        "label":"child2211",
                        "item":[
                           {
                              "id":21111,
                              "label":"child22111"
                           }
                        ]
                     }
                  ]
               },
               {
                  "id":222,
                  "label":"child32"
               }
            ]
         },
         {
            "id":22,
            "label":"child2",
            "item":[
               {
                  "id":221,
                  "label":"child421",
                  "item":[
                     {
                        "id":2211,
                        "label":"child2211"
                     }
                  ]
               },
               {
                  "id":222,
                  "label":"child222"
               }
            ]
         }
      ]
   },
   {
      "id":2,
      "label":"parent2",
      "item":[
         {
            "id":21,
            "label":"child2",
            "item":[
               {
                  "id":511,
                  "label":"child51",
                  "item":[
                     {
                        "id":5111,
                        "label":"child5211",
                        "item":[
                           {
                              "id":51111,
                              "label":"child52111"
                           }
                        ]
                     }
                  ]
               },
               {
                  "id":522,
                  "label":"child352"
               }
            ]
         }
      ]
   }
]

//ouptput selected value

{
   "id":211,
   "label":"child31",
   "selected":true,
   "item":[
      {
         "id":2111,
         "label":"child2211",
         "item":[
            {
               "id":21111,
               "label":"child22111"
            }
         ]
      }
   ]
}

我建议使用字符串方法,比如

- `includes` or
- `startsWith`

连同所需的参数。

search = (array, type, value) => array.some(o => {
    if (o.label[type](value)) return o.selected = true;
    return search(o.item || [], type, value);
})

您可以执行 ,修改找到的 属性,然后将 true 传回树的根部,沿途应用 showTree: true

请注意,这是一种就地方法,因此语义与您在通话中显示的略有不同。这可能最适合像这样的算法,它只是修改现有结构的一些属性,而不是从头开始重新分配整个事物。它是 return 就地算法的原始结构的反模式,正如 .sort().reverse() 为链接目的所做的那样——这可能会导致令人惊讶和微妙的错误。

const expandPath = (nodes, targetLabel) => {
  for (const node of nodes || []) {
    if (node.label.includes(targetLabel)) {
      return node.selected = true;
    }
    else if (expandPath(node.item, targetLabel)) {
      return node.showTree = true;
    }
  }
};

const testData = [ { id: 1, label: 'parent1', item: [ { id: 21, label: 'child1', item: [ { id: 211, label: 'child31', item: [ { id: 2111, label: 'child2211', item: [ { id: 21111, label: 'child22111' } ] } ] }, { id: 222, label: 'child32' } ] }, { id: 22, label: 'child2', item: [ { id: 221, label: 'child421', item: [ { id: 2211, label: 'child2211' } ] }, { id: 222, label: 'child222' } ] } ] }, { id: 2, label: 'parent2', item: [ { id: 21, label: 'child2', item: [ { id: 511, label: 'child51', item: [ { id: 5111, label: 'child5211', item: [ { id: 51111, label: 'child52111' } ] } ] }, { id: 522, label: 'child352' } ] } ] } ];

expandPath(testData, "child3");
console.log(testData[0]);

请注意,添加的属性位于每个节点的底部。

此外,在您最初的尝试中,请避免使用 map 进行就地操作——其目的是分配一个新数组,而不是修改它。请改用 forEach