从对象的嵌套数组中查找属性键名称

时间:2019-12-19 19:18:04

标签: javascript arrays lodash

我有一个对象数组,我需要在“ selected”为true的情况下获取“ code”值。在任何情况下,selected仅对一项有效。我已经完成了实现,有什么方法可以改进吗?

const data = [
  {
    "id": "1",
    "code": "A",
    "selected": true,
    "defaultCollapsed": false,
    "label": "A",
    "items": [
      {
        "id": "A1",
        "code": "A1",
        "label": "A-1 PP",
        "selected": true,
        "defaultCollapsed": false,
        "url": "#A1"
      },
      {
        "id": "A2",
        "code": "A2",
        "label": "A-2 ST",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A2"
      },
      {
        "id": "A3",
        "code": "A3",
        "label": "A-3 SR",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A3"
      },
      {
        "id": "A4",
        "code": "A4",
        "label": "A-4 BLS",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A4"
      },
      {
        "id": "A5",
        "code": "A5",
        "label": "A-5 BIFO",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A5"
      },
      {
        "id": "A6",
        "code": "A6",
        "label": "A-6 VA",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A6"
      }
    ]
  },
  {
    "id": "2",
    "code": "B",
    "selected": false,
    "defaultCollapsed": true,
    "label": "B. ECQG",
    "items": [
      {
        "id": "B1",
        "code": "B1",
        "label": "B-1 VR",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#B1"
      }
    ]
  },
  {
    "id": "3",
    "code": "C",
    "selected": false,
    "defaultCollapsed": true,
    "label": "C. CRR",
    "items": [
      {
        "id": "C1",
        "code": "C1",
        "label": "C-1 RSR",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#C1"
      },
      {
        "id": "C2",
        "code": "C2",
        "label": "C-2 Other",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#C2"
      }
    ]
  }
]

console.log(_.find(_.find(data, item => _.find(item.items, item1 => item1.selected)).items, item3 => item3.selected).code)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

在上面的示例中,预期的结束输出为“ A1”。 请指教。

3 个答案:

答案 0 :(得分:3)

通过Array.flatMap()将项目平铺到单个数组中,然后使用Array.find()获取所选项目:

const data = [{"id":"1","code":"A","selected":true,"defaultCollapsed":false,"label":"A","items":[{"id":"A1","code":"A1","label":"A-1 PP","selected":true,"defaultCollapsed":false,"url":"#A1"},{"id":"A2","code":"A2","label":"A-2 ST","selected":false,"defaultCollapsed":true,"url":"#A2"},{"id":"A3","code":"A3","label":"A-3 SR","selected":false,"defaultCollapsed":true,"url":"#A3"},{"id":"A4","code":"A4","label":"A-4 BLS","selected":false,"defaultCollapsed":true,"url":"#A4"},{"id":"A5","code":"A5","label":"A-5 BIFO","selected":false,"defaultCollapsed":true,"url":"#A5"},{"id":"A6","code":"A6","label":"A-6 VA","selected":false,"defaultCollapsed":true,"url":"#A6"}]},{"id":"2","code":"B","selected":false,"defaultCollapsed":true,"label":"B. ECQG","items":[{"id":"B1","code":"B1","label":"B-1 VR","selected":false,"defaultCollapsed":true,"url":"#B1"}]},{"id":"3","code":"C","selected":false,"defaultCollapsed":true,"label":"C. CRR","items":[{"id":"C1","code":"C1","label":"C-1 RSR","selected":false,"defaultCollapsed":true,"url":"#C1"},{"id":"C2","code":"C2","label":"C-2 Other","selected":false,"defaultCollapsed":true,"url":"#C2"}]}]

const result = data
  .flatMap(o => o.items) // flatten items to a single array
  .find(o => o.selected === true) // find the item

console.log(result)

lodash版本使用相同的原理:

const data = [{"id":"1","code":"A","selected":true,"defaultCollapsed":false,"label":"A","items":[{"id":"A1","code":"A1","label":"A-1 PP","selected":true,"defaultCollapsed":false,"url":"#A1"},{"id":"A2","code":"A2","label":"A-2 ST","selected":false,"defaultCollapsed":true,"url":"#A2"},{"id":"A3","code":"A3","label":"A-3 SR","selected":false,"defaultCollapsed":true,"url":"#A3"},{"id":"A4","code":"A4","label":"A-4 BLS","selected":false,"defaultCollapsed":true,"url":"#A4"},{"id":"A5","code":"A5","label":"A-5 BIFO","selected":false,"defaultCollapsed":true,"url":"#A5"},{"id":"A6","code":"A6","label":"A-6 VA","selected":false,"defaultCollapsed":true,"url":"#A6"}]},{"id":"2","code":"B","selected":false,"defaultCollapsed":true,"label":"B. ECQG","items":[{"id":"B1","code":"B1","label":"B-1 VR","selected":false,"defaultCollapsed":true,"url":"#B1"}]},{"id":"3","code":"C","selected":false,"defaultCollapsed":true,"label":"C. CRR","items":[{"id":"C1","code":"C1","label":"C-1 RSR","selected":false,"defaultCollapsed":true,"url":"#C1"},{"id":"C2","code":"C2","label":"C-2 Other","selected":false,"defaultCollapsed":true,"url":"#C2"}]}]

const result = _.find(_.flatMap(data, 'items'), 'selected')

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

答案 1 :(得分:1)

您可以使用两个嵌套的dtable <- datatable( dat, rownames = FALSE, options = list( rowsGroup = list(0,4))) # merge cells of column 1 and 5 函数来实现此目的:

reduce()

答案 2 :(得分:1)

没有太多需要改进的地方。查找将在第一个值为true时停止。

唯一的改进空间可能是使其更具可读性,并且仅使用本机JavaScript。

const data = [
  {
    "id": "1",
    "code": "A",
    "selected": true,
    "defaultCollapsed": false,
    "label": "A",
    "items": [
      {
        "id": "A1",
        "code": "A1",
        "label": "A-1 PP",
        "selected": true,
        "defaultCollapsed": false,
        "url": "#A1"
      },
      {
        "id": "A2",
        "code": "A2",
        "label": "A-2 ST",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A2"
      },
      {
        "id": "A3",
        "code": "A3",
        "label": "A-3 SR",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A3"
      },
      {
        "id": "A4",
        "code": "A4",
        "label": "A-4 BLS",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A4"
      },
      {
        "id": "A5",
        "code": "A5",
        "label": "A-5 BIFO",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A5"
      },
      {
        "id": "A6",
        "code": "A6",
        "label": "A-6 VA",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#A6"
      }
    ]
  },
  {
    "id": "2",
    "code": "B",
    "selected": false,
    "defaultCollapsed": true,
    "label": "B. ECQG",
    "items": [
      {
        "id": "B1",
        "code": "B1",
        "label": "B-1 VR",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#B1"
      }
    ]
  },
  {
    "id": "3",
    "code": "C",
    "selected": false,
    "defaultCollapsed": true,
    "label": "C. CRR",
    "items": [
      {
        "id": "C1",
        "code": "C1",
        "label": "C-1 RSR",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#C1"
      },
      {
        "id": "C2",
        "code": "C2",
        "label": "C-2 Other",
        "selected": false,
        "defaultCollapsed": true,
        "url": "#C2"
      }
    ]
  }
]

console.log(_.find(_.find(data, item => _.find(item.items, item1 => item1.selected)).items, item3 => item3.selected).code)

// More readable than above
// Find is the best option as it stops once the condition is true
function findSelected(dataToSearch) {
   let childIndex = -1;
   const parentIndex = dataToSearch.findIndex((codedData) => {
       return childIndex = codedData.items.findIndex(anotherCodedData => anotherCodedData.selected)
   });
   if (parentIndex != -1 && childIndex =! -1) { return dataToSearch[parentIndex].items[childIndex] }
   return null
}
const foundData = findSelected(data);
if (foundData) { console.log(foundData.code) }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>