Reputation: 2675
I have an array of objects and I need to get the "code" value where "selected" is true. At any instance, selected will be true only for one item. I have an implementation done and is there any way to improve upon it?
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>
Expected End output is “A1” for the above example. Please advice.
Upvotes: 0
Views: 111
Reputation: 1426
There is not much to improve upon. Find will stop at the first value being true.
The only room for improvement might be to make it more readable and only use native 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>
Upvotes: 1
Reputation: 12209
You can achieve this with two nested reduce()
functions:
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 res = data.reduce((acc1,cur1) => {
if(cur1.selected){
return cur1.items.reduce((acc2,cur2) => {
return cur2.selected ? acc2.concat(cur2.id) : acc2
},[])
}else{
return acc1
}
},[])
console.log(res)
Upvotes: 1
Reputation: 191976
Flatten the items to a single array via Array.flatMap()
, and then use Array.find()
to get the selected item:
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)
The lodash version that uses the same principles:
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>
Upvotes: 3