Flatten array of objects having arrays nested within their properties - javascript

Currently I have an array that contains my clothing (fictitious data):
myClothes = [
{
type: 'shirts',
pieces: [
{
brand: 'patagonia',
quantity: 6,
},
{
brand: 'hugo boss',
quantity: 3,
},
],
},
{
type: 'trousers',
pieces: [
{
brand: 'jack & jones',
quantity: 2,
},
{
brand: 'zara',
quantity: 4,
},
{
brand: 'versace',
quantity: 1,
},
],
},
{
type: 'socks',
pieces: [
{
brand: 'no-name',
quantity: 12,
},
],
},
];
As you see, the array contains objects (shirts, trousers, socks), that seperate the clothing by their type. Now, what can I do with javascript to make a new array of that which looks like this below here?
So where just all pieces are unseperated from shirts/trousers/socks, and it should just show how much articles I have of the brand.
allPiecesUnseperated = [
{
brand: 'patagonia',
quantity: 6,
},
{
brand: 'hugo boss',
quantity: 3,
},
{
brand: 'jack & jones',
quantity: 2,
},
{
brand: 'zara',
quantity: 4,
},
{
brand: 'versace',
quantity: 1,
},
{
brand: 'no-name',
quantity: 12,
},
];

const clothes = [{
type: 'shirts',
pieces: [{
brand: 'patagonia',
quantity: 6,
},
{
brand: 'hugo boss',
quantity: 3,
},
],
},
{
type: 'trousers',
pieces: [{
brand: 'jack & jones',
quantity: 2,
},
{
brand: 'zara',
quantity: 4,
},
{
brand: 'versace',
quantity: 1,
},
],
},
{
type: 'socks',
pieces: [{
brand: 'no-name',
quantity: 12,
}, ],
},
];
const result = clothes.map(({
pieces
}) => pieces).reduce((acc, arr) => [...acc, ...arr], []);
console.log(result);

Use .flatMap() function
const myClothes = [
{
type: 'shirts',
pieces: [
{ brand: 'patagonia', quantity: 6 },
{ brand: 'hugo boss', quantity: 3 }
]
},
{
type: 'trousers',
pieces: [
{ brand: 'jack & jones', quantity: 2 },
{ brand: 'zara', quantity: 4, },
{ brand: 'versace', quantity: 1 }
]
},
{
type: 'socks',
pieces: [
{ brand: 'no-name', quantity: 12 },
]
}
];
const output = myClothes.flatMap(o => o.pieces);
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Probably not the most efficient (since concat does create a new array everytime it is invoked) or the most elegant solution, but should get the job done.
var all = []
myClothes.forEach((item) => {
all = all.concat(item.pieces)
})

Related

How to reduce an array and add a count as a new field?

I have an array of objects, however i need the array to add a count onto each object, and also remove any duplicates. Is there a simple way to achieve this?
CURRENT
[
{ id: 2, name: 'Adventure' },
{ id: 6, name: 'Crime' },
{ id: 2, name: 'Adventure' },
{ id: 3, name: 'Beautiful' },
{ id: 7, name: 'Drama' },
{ id: 2, name: 'Adventure' }
]
EXPECTED
[
{ id: 2, name: 'Adventure', count: 3 },
{ id: 6, name: 'Crime', count: 1 },
{ id: 3, name: 'Beautiful', count: 1 },
{ id: 7, name: 'Drama', count: 1 }
]
let current = [
{ id: 2, name: 'Adventure' },
{ id: 6, name: 'Crime' },
{ id: 2, name: 'Adventure' },
{ id: 3, name: 'Beautiful' },
{ id: 7, name: 'Drama' },
{ id: 2, name: 'Adventure' }
]
let expected = current.reduce((acc, cur) => {
let curFind = acc.find(item => item.id === cur.id)
if (curFind) {
curFind.count++
return acc
} else {
return [...acc, {
...cur,
count: 1
}]
}
}, [])
console.log('expected:', expected)

create new arraylist from existing arraylistt

I have a nested data from API. I need only some values and objects from that array list.
So, I'm trying to new simple array list but I couldn't handle with array in it.
I'll explain with sample:
const dummyData = [
{
orderDate: '20220501',
orderNumber: '12345',
id: '1',
name: 'Customer 1',
lines: [
{ id: 1, product: 'PRD001', qty: 1},
{ id: 2, product: 'PRD002', qty: 3},
]
},
{
orderDate: '20220501',
orderNumber: '12346',
id: '2',
name: 'Customer 2',
lines: [
{ id: 1, product: 'PRD001', qty: 1 },
{ id: 2, product: 'PRD002', qty: 2 },
{ id: 3, product: 'PRD003', qty: 7 },
{ id: 4, product: 'PRD004', qty: 1 },
]
},
{
orderDate: '20220502',
orderNumber: '12347',
id: '3',
name: 'Customer 3',
lines: [
{ id: 1, product: 'PRD001', qty: 1 },
{ id: 2, product: 'PRD002', qty: 1 },
{ id: 3, product: 'PRD003', qty: 3 },
]
},
]
const currentData = data.map(order => (
{
orderDate: order.orderDate,
orderNumber: order.orderNumber,
lines:
order["lines"].map(line => ({
product: line.product,
qty: line.qty,
}))
}
))
console.log("order", currentData)
The output is:
[{"lines": [[Object], [Object]], "orderDate": "20220501", "orderNumber": "12345"}, {"lines": [[Object], [Object], [Object], [Object]], "orderDate": "20220501", "orderNumber": "12346"}, {"lines": [[Object], [Object], [Object]], "orderDate": "20220502", "orderNumber": "12347"}]
But I'm trying to create a new array list like this:
[{
"lines": [
{ product: 'PRD001', qty: 1
},
{ product: 'PRD002', qty: 3
},
],
"orderDate": "20220501",
"orderNumber": "12345"
}]
What i'm trying to do:
[
{
orderDate: '20220501',
orderNumber: '12345',
lines: [
{ id: 1, product: 'PRD001', qty: 1},
{ id: 2, product: 'PRD002', qty: 3},
]
},
{
orderDate: '20220501',
orderNumber: '12346',
lines: [
{ product: 'PRD001', qty: 1 },
{ product: 'PRD002', qty: 2 },
{ product: 'PRD003', qty: 7 },
{ product: 'PRD004', qty: 1 },
]
},
{
orderDate: '20220502',
orderNumber: '12347',
lines: [
{ product: 'PRD001', qty: 1 },
{ product: 'PRD002', qty: 1 },
{ product: 'PRD003', qty: 3 },
]
},
]

Get unique values from array values in json array

I'm writing a code where I need to return uniques values from a JSON array. Here my challenge is, I've got these values as an array for one of the keys.
Here is my code.
let mobilePhones = [{
id: 1,
brand: ["B1", "B2"]
}, {
id: 2,
brand: ["B2"]
}, {
id: 3,
brand: ["B1", "B2"]
}, {
id: 4,
brand: ["B1"]
}, {
id: 5,
brand: ["B2", "B1"]
}, {
id: 6,
brand: ["B3"]
}]
let allBrandsArr = mobilePhones.map(row => {
return row.brand;
});
let uniqueBrands = allBrandsArr.filter((item, index, arry) => (arry.indexOf(item) === index));
console.log(JSON.stringify(uniqueBrands));
Here my expected result is to get ["B1", "B2", "B3"]. Please let me know how can I achieve this.
Updated new sample data:
let mobilePhones = [{
id: 1,
brand: ["B1, B2"]
}, {
id: 2,
brand: ["B2"]
}, {
id: 3,
brand: ["B1, B2"]
}, {
id: 4,
brand: ["B1"]
}, {
id: 5,
brand: ["B2, B1"]
}, {
id: 6,
brand: ["B3"]
}]
let allBrandsArr = mobilePhones.map(row => {
return row.brand;
});
Thanks
You need to use flat for merge sub array then your code was good:
let mobilePhones = [{
id: 1,
brand: ["B1, B2"]
}, {
id: 2,
brand: ["B2"]
}, {
id: 3,
brand: ["B1, B2"]
}, {
id: 4,
brand: ["B1"]
}, {
id: 5,
brand: ["B2, B1"]
}, {
id: 6,
brand: ["B3"]
}]
let allBrandsArr = mobilePhones.map(row => {
return row.brand[0].split(',').map(function(item) {
return item.trim();
});
});
let uniqueBrands = allBrandsArr.flat().filter((item, index, arry) => (arry.indexOf(item) === index));
console.log(JSON.stringify(uniqueBrands));
Reference:
Array.prototype.flat()
After new Data posted i add split with trim.
Reference:
String.prototype.split()
String.prototype.trim()
You can use .flatMap to get all the brand values and pass it to a Set to make it unique.
const uniqueBrands = [...new Set(mobilePhones.flatMap(({
brand
}) => brand))];
let mobilePhones = [{
id: 1,
brand: ["B1", "B2"]
}, {
id: 2,
brand: ["B2"]
}, {
id: 3,
brand: ["B1", "B2"]
}, {
id: 4,
brand: ["B1"]
}, {
id: 5,
brand: ["B2", "B1"]
}, {
id: 6,
brand: ["B3"]
}]
const unique = [...new Set(mobilePhones.flatMap(({
brand
}) => brand))];
console.log(unique);

How to duplicate an object in an array by given quantity, ES6 and above

I'm trying to convert an array of objects where i return duplicated objects if the object properties quantity is greater than 1.
const objects = [
{ id: 1, name: "Scissor", price: 2, quantity: 3 },
{ id: 2, name: "Hat", price: 6.5, quantity: 1 },
{ id: 3, name: "Socks", price: 0.5, quantity: 5 },
];
// desired return
[
{ id: 1, name: "Scissor", price: 2 }
{ id: 1, name: "Scissor", price: 2 }
{ id: 1, name: "Scissor", price: 2 }
{ id: 2, name: "Hat", price: 6.5}
{ id: 3, name: "Socks", price: 0.5 }
{ id: 3, name: "Socks", price: 0.5 }
{ id: 3, name: "Socks", price: 0.5 }
{ id: 3, name: "Socks", price: 0.5 }
{ id: 3, name: "Socks", price: 0.5 }
]
My code:
const objects = [
{ id: 1, name: "Scissor", price: 2, quantity: 3 },
{ id: 2, name: "Hat", price: 6.5, quantity: 1 },
{ id: 3, name: "Socks", price: 0.5, quantity: 5 },
];
let newObjects= [];
Object.entries(objects).forEach(([key, value]) => {
for (let i=0; i < value.quantity; i++){
newObjects.push({ id: value.id, name: value.name, price: value.price})
}
});
console.log(newObjects);
So my code above does work, does return what i wanted, however i feel like there is a better/smoother and more of ES6 and beyond method. Could anyone please suggest a better way?
You could use .fill() and .flatMap().
const objects = [
{ id: 1, name: "Scissor", price: 2, quantity: 3 },
{ id: 2, name: "Hat", price: 6.5, quantity: 1 },
{ id: 3, name: "Socks", price: 0.5, quantity: 5 },
];
let newObjects = objects.flatMap(e=>
Array(e.quantity).fill({id: e.id, name: e.name, price: e.price})
);
console.log(newObjects);
You can use an array reduce along with an array fill.
The map is required only if you want to have unique references otherwise you can fill using the same object.
const objects = [
{ id: 1, name: "Scissor", price: 2, quantity: 3 },
{ id: 2, name: "Hat", price: 6.5, quantity: 1 },
{ id: 3, name: "Socks", price: 0.5, quantity: 5 },
];
const output = objects.reduce((a, c) => {
return a.concat(Array(c.quantity).fill({}).map(x=>({
id: c.id,
name: c.name,
price: c.price
})))
}, []);
console.log(output)

get name of object in array when option.amount equals zero

I'm trying to get an array of names of objects that have options.amount all equals to zero. Thanks for your time. This is what i tryed:
let variants = [
{
name: 'extra',
options: [
{
name: 'meat',
price: 3,
amount: 0
},
{
name: 'cheese',
price: 1,
amount: 0
}
]
},
{
name: 'sauce',
options: [
{
name: 'ketchup',
price: 2,
amount: 1
},
{
name: 'mayo',
price: 1,
amount: 0
}
]
}
];
//Expected output = ['extra']
let arrayOfOptionsNames = variants.map(x => x.options.filter(y => y.amount === 0 ? x.name : 0))
console.log(arrayOfOptionsNames)
You could use Array.prototype.filter() and Array.prototype.every() method to get your result. Every method test if every elements of the array pass the test by the given callback function and returns a boolean value.
const variants = [
{
name: 'extra',
options: [
{
name: 'meat',
price: 3,
amount: 0,
},
{
name: 'cheese',
price: 1,
amount: 0,
},
],
},
{
name: 'sauce',
options: [
{
name: 'ketchup',
price: 2,
amount: 1,
},
{
name: 'mayo',
price: 1,
amount: 0,
},
],
},
];
const ret = variants
.filter((x) => x.options.every((y) => y.amount === 0))
.map((x) => x.name);
console.log(ret);
You could filter and get the wanted property.
let variants = [{ name: 'extra', options: [{ name: 'meat', price: 3, amount: 0 }, { name: 'cheese', price: 1, amount: 0 }] }, { name: 'sauce', options: [{ name: 'ketchup', price: 2, amount: 1 }, { name: 'mayo', price: 1, amount: 0 }] }],
result = variants
.filter(({ options }) => options.every(({ amount }) => !amount))
.map(({ name }) => name);
console.log(result);

Categories

Resources