There are two arrays:
const products = [
{
id: 123,
stock: [
{
colors: [{ color: "red", stock: 12 }],
size: "S",
},
],
},
{
id: 321,
stock: [
{
colors: [{ color: "blue", stock: 10 }],
size: "L",
},
],
},
];
and
const incart = [
{
id: 123,
color: "red",
qty: 1,
size: "S",
},
{
id: 321,
color: "blue",
size: "L",
qty: 2,
},
];
When a user purchases the items they have in their cart. I'd like to update the products array stock object if the color and size match.
I'm thinking about a filter and reduce but not sure how to implement it.
You can easily achieve this using forEach and find
const products = [
{
id: 123,
stock: [
{
colors: [{ color: "red", stock: 12 }],
size: "S",
},
],
},
{
id: 321,
stock: [
{
colors: [{ color: "blue", stock: 10 }],
size: "L",
},
],
},
];
const incart = [
{
id: 123,
color: "red",
qty: 1,
size: "S",
},
{
id: 321,
color: "blue",
size: "L",
qty: 2,
},
];
incart.forEach((curr) => {
const { id, color, qty, size } = curr;
const isExist = products.find((obj) => obj.id === id);
if (isExist) {
const stockObj = isExist.stock.find((s) => s.size === size);
if (stockObj) {
const colorObj = stockObj.colors.find((c) => c.color === color);
if (colorObj) colorObj.stock -= qty;
}
}
});
console.log(products);
Related
Having issues with this exercise:
// Let’s say we have an array of artists and we want to create a map-like object of their instruments.
const artists = [
{
id: '1',
name: 'Jimi Hendrix',
instrument: {
id: '1',
name: 'Guitar',
color: 'wood',
}
},
{
id: '2',
name: 'Jimmy Page',
instrument: {
id: '1',
name: 'Guitar',
color: 'wood',
}
},
{
id: '3',
name: 'Krist Novoselic',
instrument: {
id: '2',
name: 'Bass',
color: 'black',
}
},
{
id: '4',
name: 'Emmanuelle Proulx',
},
{
id: '5',
name: 'Jimmy Chamberlin',
instrument: {
id: '3',
name: 'Drums'
}
},
];
/* Expected results */
/* {
1: {
name: 'Guitar',
color: 'wood',
},
...
} */
const result = [];
artists.map((item) => {if ((item.instrument !== undefined)) {result.push(item.instrument.id = item.instrument)}});
So far I've extracted th instruments without undefined, but the ids are reference to ids and cannot get to extract the number id or to build it with the proper structure because of the circular reference.
So to use the map you'd still get undefined values. You probably would want to use reduce and do the following.
const artists = [
{
id: "1",
name: "Jimi Hendrix",
instrument: {
id: "1",
name: "Guitar",
color: "wood",
},
},
{
id: "2",
name: "Jimmy Page",
instrument: {
id: "1",
name: "Guitar",
color: "wood",
},
},
{
id: "3",
name: "Krist Novoselic",
instrument: {
id: "2",
name: "Bass",
color: "black",
},
},
{
id: "4",
name: "Emmanuelle Proulx",
},
{
id: "5",
name: "Jimmy Chamberlin",
instrument: {
id: "3",
name: "Drums",
},
},
];
const instruments = artists.reduce((acc, artist) => {
if (!artist.instrument) return acc;
const { id, name, color } = artist.instrument;
acc[id] = { name, color };
return acc;
}, {});
console.log(instruments);
try this
const instruments = artists.reduce((acc, artist) => {
if (!artist.instrument) return acc;
acc[artist.instrument.id] = {
name: artist.instrument.name,
color: artist.instrument.color
};
return acc;
}, {});
result
{
"1": {
"name": "Guitar",
"color": "wood"
},
"2": {
"name": "Bass",
"color": "black"
},
"3": {
"name": "Drums"
}
}
const data = [
{0: {id: "1",cat:{string:[{color:"yellow",weight:"10"},{color:"orange",Weight:"10"}]}},
{1: {id: "1",cat:{string:[{color:"blue",weight:"10"},{color:"orange",Weight:"10"}]}},
{2: {id: "1",cat:{string:[{color:"white",weight:"10"},{color:"orange",Weight:"10"}]}},
{3: {id: "1",cat:{string:[{color:"blue",weight:"10"},{color:"orange",Weight:"10"}]}},
]
Filter by Color: "Yellow"
Desired Output: [{0: {id: 1, country: "SA", address: "IOXX",cat:[{color: "yellow",weight: "10"}]}}]
You can use filter() method
const data = [
{ 0: { id: "1", cat: { string: [{ color: "yellow", weight: "10" }, { color: "orange", Weight: "10" }] } } },
{ 1: { id: "1", cat: { string: [{ color: "blue", weight: "10" }, { color: "orange", Weight: "10" }] } } },
{ 2: { id: "1", cat: { string: [{ color: "white", weight: "10" }, { color: "orange", Weight: "10" }] } } },
{ 3: { id: "1", cat: { string: [{ color: "blue", weight: "10" }, { color: "orange", Weight: "10" }] } } }
];
var res = data.filter((el, i) => data[i][i]['cat']['string'][0]['color'] === 'yellow');
console.log(res);
You can map over your data array and check if each object passes your conditions or not.
const data = [
{0: {id: 1, country: "SA", address: "IOXX",cat:[{color: "yellow",weight: "10"}]}},
{1: {id:2, country: "SAP", name: "N", address: "IOP",cat:[{color: "blue",weight: "10"}]}},
{2: {id:3, country: "S", name: "NO", address: "I",cat:[{color: "blue",weight: "10"}]}},
{3: {id:4, country: "SXX", name: "NOI", address: "INDIA",cat:[{color: "blue",weight: "12"}]}},
]
const filterByColor = function (color) {
const filteredCats = []
data.forEach((item, index) => {
const hasCorrectColor = item[index].cat.every((cat) => cat.color === color)
if (hasCorrectColor) {
filteredCats.push(item)
}
})
return filteredCats
}
filterByColor('yellow')
So I have an array of products.
One of the products is structured like this:
[ {
sizes: [
{
size: 'S',
colors: [
{color: 'gray', stock: 10},
{color: 'black', stock: 0}
],
},
{
size: 'L',
colors: [
{color: 'black', stock: 5},
{color: 'red', stock: 0}
]
}
],
...//other info
},
//other products
]
I also have two states:
const [colors, setColors] = useState([])
const [sizes, setSizes] = useState([])
So when a user is filtering by sizes and colors they have selected, I would like to filter the products array accordingly.
I would have used here HOF for syntax sugaring:
let shirts = {
sizes: [
{
size: "S",
colors: [
{ color: "gray", stock: 10 },
{ color: "black", stock: 0 }
]
},
{
size: "L",
colors: [
{ color: "black", stock: 5 },
{ color: "red", stock: 0 }
]
}
]
};
function bySizes(wantedSizes) {
return (shirt) => {
let toKeep = false;
wantedSizes.forEach((wantedSize) => {
if (shirt.size.toLowerCase() === wantedSize.toLowerCase()) toKeep = true;
});
return toKeep;
};
}
function byColors(wantedColors) {
return (shirt) => {
let toKeep = false;
shirt.colors.forEach((color) => {
wantedColors.forEach((wantedColor) => {
if (color.color === wantedColor) toKeep = true;
});
});
return toKeep;
};
}
let filteredShirts = shirts.sizes
.filter(bySizes(["S", "XS"]))
.filter(byColors(["black", "white"]))
console.log(filteredShirts);
You may try useEffect. Here is the example if the user selects the color
useEffect(() => {
const p = products.filter((product) => {return product.color == color});
setProducts([...p]);
}, [color])
I got an array like this
let p = [
{
sku: 12,
data: { name: 'pro', price: 100 },
},
{
sku: 33,
data: { name: 'pro', price: 100 },
},
{
sku: 55,
data: { name: 'pro', price: 100 },
},
{
sku: 12,
data: { name: 'pro', price: 100 },
},
]
I want to combine the duplicated item, and add extra quantity key in each object
So I will have array like this
p = [
{
sku: 12,
data: { name: 'pro', price: 100 },
quantity:2
},
{
sku: 33,
data: { name: 'so', price: 98 },
quantity:1
},
{
sku: 55,
data: { name: 'do', price: 77 },
quantity:1
},
]
How to do this?
You can use Arary.reduce() to iterate over array and create a new one based on calculations like following:
let p = [
{
sku: 12,
data: { name: 'pro', price: 100 },
},
{
sku: 33,
data: { name: 'pro', price: 100 },
},
{
sku: 55,
data: { name: 'pro', price: 100 },
},
{
sku: 12,
data: { name: 'pro', price: 100 },
},
];
var reducedArray = p.reduce((acc,item) => {
var previousItem = acc.find(findItem => findItem.sku === item.sku);
if(!previousItem){
acc.push({...item, quantity: 1})
}else{
previousItem.quantity++
}
return acc;
},[]);
console.log(reducedArray);
Hope this helps.
You can use JavaScript's reduce() method to do that.
let p = [
{
sku: 12,
data: { name: 'pro', price: 100 },
},
{
sku: 33,
data: { name: 'pro', price: 100 },
},
{
sku: 55,
data: { name: 'pro', price: 100 },
},
{
sku: 12,
data: { name: 'pro', price: 100 },
},
];
let result = p.reduce((arr, currentValue) => {
const index = arr.findIndex(item => item.sku === currentValue.sku);
if (index === -1) {
currentValue.quantity = 1;
arr.push(currentValue);
} else {
arr[index].quantity++;
}
return arr;
}, []);
console.log(result);
I am getting started with Vue. I am struggling to calculate the sum of different elements in an object of an array.
My array looks like this:
sites: [{
sku: 10001,
name: "Product A",
totalPrice: '',
values: [{
price: 10,
discount: 5,
color: "red"
},
{
price: 15,
discount: 8,
color: "black"
}]
},
{
sku: 10002,
name: "Product B",
totalPrice: '',
values: [{
price: 13,
discount: 3,
color: "purple"
},
{
price: 20,
discount: 5,
color: "green"
}]
}]
I am trying to sum the price and set it to totalPrice. So the array will change totalPrice as below:
sku: 10001,
name: "Product A",
totalPrice: 25,
sku: 10002,
name: "Product B",
totalPrice: 33,
I believe I need to use something like the below to sum them, however I cannot figure out how to do this!
computed: {
total(){ return this.sites.reduce( (total, item) => item.values. price + total ,0);}
},
How do I calculate the sum of the price and set it as the totalPrice?
I have traveled SO and find similar threads however nothing that I can get to work with my issue.
computed: {
total() {
let newojv = []
sites.forEach((item, _) => {
let s = item.values.map((items2, _) => {
return items2.price;
})
let sum = s.reduce((a, b) => a + b);
newojv.push({
sku: item.sku,
name: item.name,
totalPrice: sum
});
});
return newojv;
}
}
First for Each of the array of objects below
{
sku: 10001,
name: "Product A",
totalPrice: '',
values: [{
price: 10,
discount: 5,
color: "red"
},
{
price: 15,
discount: 8,
color: "black"
}
]
}
And then for Each of the array of objects below
values: [{
price: 10,
discount: 5,
color: "red"
},
{
price: 15,
discount: 8,
color: "black"
}
]
We take a we map the array to get the values of the price, which is 10,15. Then we reduce the array, add it and then push it.
let sum = s.reduce((a, b) => a + b);
newojv.push({
sku: item.sku,
name: item.name,
totalPrice: sum
});
A working example can be
let sites = [{
sku: 10001,
name: "Product A",
totalPrice: '',
values: [{
price: 10,
discount: 5,
color: "red"
},
{
price: 15,
discount: 8,
color: "black"
}
]
}, {
sku: 10002,
name: "Product B",
totalPrice: '',
values: [{
price: 13,
discount: 3,
color: "purple"
},
{
price: 20,
discount: 5,
color: "green"
}
]
}]
let newojv = []
sites.forEach((item, _) => {
let s = item.values.map((items2, _) => {
return items2.price;
})
let sum = s.reduce((a, b) => a + b);
newojv.push({
sku: item.sku,
name: item.name,
totalPrice: sum
});
});
console.log(newojv)