javascript - 切换对象嵌套数组的属性 - JS

标签 javascript arrays

我有一个包含 3 个级别的对象数组。我想用属性“code”来定位最里面的 child 。如果存在代码,则使用 selected: true 更新子对象和父对象。如果该属性已经为 true,则发送相同的值应将子项设置为 selected: false (切换) 这就是我到目前为止所要做的。如果子项的 selected 为 true,则发送另一个代码应为相应的子项设置 selected: true ,并为 selected 属性为 true 的子项设置 selected: false

此外,如果子项的 selected 为 true,则子项以及父项和祖项的 defaultCollapsed 属性应为 false。如果子项的 selected 为 false,则子项以及父项和祖项的 defaultCollapsed 属性应为 true

const data = [{
    "label": "Grand Parent 1",
    "index": 0,
    "code": "GRAND_PARENT_1",
    "defaultCollapsed": true,
    "items": [{
        "id": 1,
        "items": [{
            "id": 100,
            "label": "Child 1",
            "url": "#CHILD_1",
            "code": "CHILD_1",
          },
          {
            "id": 200,
            "label": "Child 2",
            "url": "#CHILD_2",
            "code": "CHILD_2"
          },
          {
            "id": 300,
            "label": "Child 3",
            "url": "#CHILD_3",
            "code": "CHILD_3"
          },
          {
            "id": 400,
            "label": "Child 4",
            "url": "#CHILD_4",
            "code": "CHILD_4"
          }
        ],
        "defaultCollapsed": true,
        "label": "Parent 1",
        "selected": true,
      },
      {
        "id": 2,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 2"
      },
      {
        "id": 3,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 3"
      },
      {
        "id": 4,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 4"
      }
    ]
  },
  {
    "label": "Grand Parent 2",
    "index": 1,
    "code": "GRAND_PARENT_2",
    "defaultCollapsed": true,
    "items": []
  },
  {
    "label": "Grand Parent 3",
    "index": 2,
    "code": "GRAND_PARENT_3",
    "defaultCollapsed": true,
    "items": []
  }
]

function select(items, key, value) {
  if (!Array.isArray(items)) {
    return false;
  }

  for (const item of items) {
    if (item.code === value || select(item.items, key, value)) {
      item.selected = !item.selected;
      item.defaultCollapsed = false;
      return true;
    }
  }

  return false;
}

function reset(items) {
  if (!Array.isArray(items)) {
    return;
  }

  for (const item of items) {
    if (item.selected) {
      reset(item.items);
      item.selected = false;
      break;
    }
  }
}

function resetAndSelect(data, key, value) {
  reset(data);
  select(data, key, value);
}

resetAndSelect(data, 'code', 'CHILD_1')

console.log('CHILD_1',data)

resetAndSelect(data, 'code', 'CHILD_2')

console.log('CHILD_2',data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

如果代码是 CHILD_1:

[{
    "label": "Grand Parent 1",
    "index": 0,
    "code": "GRAND_PARENT_1",
    "defaultCollapsed": true,
    "selected": true,
    "items": [{
        "id": 1,
        "items": [{
            "id": 100,
            "label": "Child 1",
            "url": "#CHILD_1",
            "code": "CHILD_1",
            "selected": true,
          },
          {
            "id": 200,
            "label": "Child 2",
            "url": "#CHILD_2",
            "code": "CHILD_2"
          },
          {
            "id": 300,
            "label": "Child 3",
            "url": "#CHILD_3",
            "code": "CHILD_3"
          },
          {
            "id": 400,
            "label": "Child 4",
            "url": "#CHILD_4",
            "code": "CHILD_4"
          }
        ],
        "defaultCollapsed": false,
        "label": "Parent 1",
        "selected": true,
      },
      {
        "id": 2,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 2"
      },
      {
        "id": 3,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 3"
      },
      {
        "id": 4,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 4"
      }
    ]
  },
  {
    "label": "Grand Parent 2",
    "index": 1,
    "code": "GRAND_PARENT_2",
    "defaultCollapsed": true,
    "items": []
  },
  {
    "label": "Grand Parent 3",
    "index": 2,
    "code": "GRAND_PARENT_3",
    "defaultCollapsed": true,
    "items": []
  }
]

如果上面的输出是实际数据,并且代码又是CHILD_1,我需要切换子级的选定属性以及相应的父级。

[{
    "label": "Grand Parent 1",
    "index": 0,
    "code": "GRAND_PARENT_1",
    "defaultCollapsed": true,
    "selected": false,
    "items": [{
        "id": 1,
        "items": [{
            "id": 100,
            "label": "Child 1",
            "url": "#CHILD_1",
            "code": "CHILD_1",
            "selected": false,
          },
          {
            "id": 200,
            "label": "Child 2",
            "url": "#CHILD_2",
            "code": "CHILD_2"
          },
          {
            "id": 300,
            "label": "Child 3",
            "url": "#CHILD_3",
            "code": "CHILD_3"
          },
          {
            "id": 400,
            "label": "Child 4",
            "url": "#CHILD_4",
            "code": "CHILD_4"
          }
        ],
        "defaultCollapsed": false,
        "label": "Parent 1",
        "selected": false,
      },
      {
        "id": 2,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 2"
      },
      {
        "id": 3,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 3"
      },
      {
        "id": 4,
        "items": [],
        "defaultCollapsed": true,
        "label": "Parent 4"
      }
    ]
  },
  {
    "label": "Grand Parent 2",
    "index": 1,
    "code": "GRAND_PARENT_2",
    "defaultCollapsed": true,
    "items": []
  },
  {
    "label": "Grand Parent 3",
    "index": 2,
    "code": "GRAND_PARENT_3",
    "defaultCollapsed": true,
    "items": []
  }
]

最佳答案

您可以通过使用 forEach 循环创建递归函数并通过递归传递父级数组来完成此操作,以便您可以更新其选定的属性。

const data = [{"label":"Grand Parent 1","index":0,"code":"GRAND_PARENT_1","defaultCollapsed":true,"items":[{"id":1,"items":[{"id":100,"label":"Child 1","url":"#CHILD_1","code":"CHILD_1"},{"id":200,"label":"Child 2","url":"#CHILD_2","code":"CHILD_2"},{"id":300,"label":"Child 3","url":"#CHILD_3","code":"CHILD_3"},{"id":400,"label":"Child 4","url":"#CHILD_4","code":"CHILD_4"}],"defaultCollapsed":true,"label":"Parent 1","selected":true},{"id":2,"items":[],"defaultCollapsed":true,"label":"Parent 2"},{"id":3,"items":[],"defaultCollapsed":true,"label":"Parent 3"},{"id":4,"items":[],"defaultCollapsed":true,"label":"Parent 4"}]},{"label":"Grand Parent 2","index":1,"code":"GRAND_PARENT_2","defaultCollapsed":true,"items":[]},{"label":"Grand Parent 3","index":2,"code":"GRAND_PARENT_3","defaultCollapsed":true,"items":[]}]

function update(data, key, value, parents = []) {
  data.forEach(e => {
    if (e[key] === value) {
      if (parents.length) {
        e.selected = !e.selected;

        parents.forEach(p => {
          p.defaultCollapsed = !e.selected
          p.selected = e.selected
        })

        data.forEach(s => {
          if (s != e && s.selected) s.selected = false;
        });
      }
    }

    if (e.items && e.items.length) {
      update(e.items, key, value, [...parents, e])
    }
  })
}

update(data, 'code', 'CHILD_4')
update(data, 'code', 'CHILD_4')
update(data, 'code', 'CHILD_2')
update(data, 'code', 'CHILD_1')
console.log(data)

关于javascript - 切换对象嵌套数组的属性 - JS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59095052/

相关文章:

c - 我想打印输入字符串中以空格分隔的单词

php - 使用 PHP 动态验证 HTML 表单

javascript - react : How to select multiple images using react-image-picker

javascript - 多次读取数组会出现错误javascript

c# - 如何使用 PLinq 将二维文本文件读入二维数组

python - 当我取数组列的中位数时,如何忽略零?

javascript - three.js 使用A-frame 会影响three.js 吗?

javascript - 用于转到鼠标坐标的 Canvas 动画

javascript - JavaScript 中惯用的嵌套 for 循环

c++ - 在 C++ 中使用分隔符获取输入