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

时间:2019-11-28 19:13:23

标签: javascript arrays

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

此外,如果为孩子选择的值为true,则对于孩子以及父项和祖父母的defaultCollapsed属性应为false。如果为孩子选择的false为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": []
  }
]

2 个答案:

答案 0 :(得分:1)

您可以通过使用let variable = match list_of_chars with | '#'::l1@['!']@l2 -> (*[code to do something with l1 and l2]*) | _ -> raise Exception ;; 循环创建递归函数,并通过递归向下传递父级数组来做到这一点,以便更新其选定的属性。

forEach

答案 1 :(得分:1)

对于项目的路径,您可以切换目标节点并将其余节点保留为true。

function update(array, value) {
    var found = false;
    array.forEach(o => {
        var sub = update(o.items || [], value),
            check = o.code === value;

        if (check) {
            o.selected = !o.selected
            found = o.selected;
        } else {
            o.selected = sub;
            if (sub) found = o.selected;
        }
        o.defaultCollapsed = !o.selected;
    });
    return found;
}

var 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: false, label: "Parent 1" }, { 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: [] }];

update(data, 'CHILD_1');
console.log(data);
update(data, 'CHILD_1');
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }