I have a list of all available stock items with a unique stock id and detail attributes. From the UI, I collect customer selection, based on the unique value code in customer selection, I would like to find the selected item from the stock items. That is,
What is the best approach to find stockItem from availableStock that matches the value code attribute in customerSelection array list? Please have a look at the example below:
const customerSelection = {
"tv": [
{
"value": "tv_40",
"label": "Flat Screen"
}
],
"keyboard": [
{
"value": "keyboard_40",
"label": "Wireless Keyboard"
}
],
"mouse": [
{
"value": "mouse_40",
"label": "Wireless Mouse"
}
]
};
const availableStock = [
{
"stockId": "elec_c1_f1",
"attributes": [
{
"label": "Flat Screen",
"value": "tv_41"
},
{
"label": "Wireless Keyboard",
"value": "keyboard_41"
},
{
"label": "Wireless Mouse",
"value": "mouse_41"
}
]
},
{
"stockId": "elec_c1_f2",
"attributes": [
{
"label": "Flat Screen",
"value": "tv_40"
},
{
"label": "Wireless Keyboard",
"value": "keyboard_40"
},
{
"label": "Wireless Mouse",
"value": "mouse_40"
}
]
},
{
"stockId": "elec_c1_f3",
"attributes": [
{
"label": "Flat Screen",
"value": "tv_42"
},
{
"label": "Wireless Keyboard",
"value": "keyboard_42"
},
{
"label": "Wireless Mouse",
"value": "mouse_42"
}
]
}
]
Expected result with stockId (or Just the stockId)
const stockItem = {
"stockId": "elec_c1_f2",
"attributes": [
{
"label": "Flat Screen",
"value": "tv_40"
},
{
"label": "Wireless Keyboard",
"value": "keyboard_40"
},
{
"label": "Wireless Mouse",
"value": "mouse_40"
}
]
}
Any suggestion with/without lodash is appreciated.
CodePudding user response:
Firstly get all keys from customer selection:
var values = Object.keys(customerSelection).map(element =>customerSelection[element][0].value)
Then get matchedAvailableValues by using this code:
var matchedAvailableValues = availableStock.filter(element => values.includes(element.attributes[0].value) ? {stockId:element.stockId,attributes:element.attributes} : false);
So your final code look like this:
var values = Object.keys(customerSelection).map(element => customerSelection[element][0].value)
var matchedValues = availableStock.filter(element => values.includes(element.attributes[0].value) ? {stockId:element.stockId,attributes:element.attributes}:false);
CodePudding user response:
Use nested for..in loops to navigate both objects.
const customerSelection = {
"tv": [
{
"value": "tv_41",
"label": "Flat Screen"
}
],
"keyboard": [
{
"value": "keyboard_40",
"label": "Wireless Keyboard"
}
],
"mouse": [
{
"value": "mouse_40",
"label": "Wireless Mouse"
}
]
};
const availableStock = [
{
"stockId": "elec_c1_f1",
"attributes": [
{
"label": "Flat Screen",
"value": "tv_41"
},
{
"label": "Wireless Keyboard",
"value": "keyboard_41"
},
{
"label": "Wireless Mouse",
"value": "mouse_41"
}
]
},
{
"stockId": "elec_c1_f2",
"attributes": [
{
"label": "Flat Screen",
"value": "tv_40"
},
{
"label": "Wireless Keyboard",
"value": "keyboard_40"
},
{
"label": "Wireless Mouse",
"value": "mouse_40"
}
]
},
{
"stockId": "elec_c1_f3",
"attributes": [
{
"label": "Flat Screen",
"value": "tv_42"
},
{
"label": "Wireless Keyboard",
"value": "keyboard_42"
},
{
"label": "Wireless Mouse",
"value": "mouse_42"
}
]
}
];
for (o in customerSelection)
for (p in availableStock)
for (q in availableStock[p].attributes)
if (customerSelection[o][0].value==availableStock[p].attributes[q].value) console.log(availableStock[p].stockId);
CodePudding user response:
I'd suggest creating a requiredValues array, using Array.values() and Array.map().
This will look like:
[ "tv_40", "keyboard_40", "mouse_40" ]
We'd then use Array.filter() to find all stock items with every required value present in its attributes.
We'd use Array.every(), along with Array.find() to ensure every required value is present in the item attributes.
This would return a list of the stock items.
We can then map to get a list of matching stock ids:
const customerSelection = { "tv": [ { "value": "tv_40", "label": "Flat Screen" } ], "keyboard": [ { "value": "keyboard_40", "label": "Wireless Keyboard" } ], "mouse": [ { "value": "mouse_40", "label": "Wireless Mouse" } ] };
const availableStock = [ { "stockId": "elec_c1_f1", "attributes": [ { "label": "Flat Screen", "value": "tv_41" }, { "label": "Wireless Keyboard", "value": "keyboard_41" }, { "label": "Wireless Mouse", "value": "mouse_41" } ] }, { "stockId": "elec_c1_f2", "attributes": [ { "label": "Flat Screen", "value": "tv_40" }, { "label": "Wireless Keyboard", "value": "keyboard_40" }, { "label": "Wireless Mouse", "value": "mouse_40" } ] }, { "stockId": "elec_c1_f3", "attributes": [ { "label": "Flat Screen", "value": "tv_42" }, { "label": "Wireless Keyboard", "value": "keyboard_42" }, { "label": "Wireless Mouse", "value": "mouse_42" } ] } ]
// These values must be present in the attributes...
const requiredValues = Object.values(customerSelection).map(val => val[0].value);
// Use Array.filter() to find stock items that match _all_ required attributes...
const foundItems = availableStock.filter(item => {
return requiredValues.every(value => item.attributes.find(attr => attr.value === value));
});
console.log('Found stockIds:', foundItems.map(({ stockId }) => stockId));
console.log('Found items:', foundItems);
.as-console-wrapper { max-height: 100% !important; top: 0; }
