This question already has an answer here:
How to merge two list of objects in a new one by date
(1 answer)
Closed 8 months ago.
I'm learning Javascript and I'm stuck in a doubt with the joining of two arrays of objects through an ID, I can join the two, but the result is not what I expect.
So, I have these two object arrays:
"product": [
{
"id": "1000",
"code": "f230fh0g3",
"name": "Bamboo Watch",
"description": "Product Description",
"image": "bamboo-watch.jpg",
"price": 65,
"category": "Accessories",
"quantity": 24,
}
]
"orders": [
{
"id": "1000",
"productID": "f230fh0g3",
"date": "2020-09-13",
"amount": 65,
"quantity": 1,
},
{
"id": "1000",
"productID": "f230fh0g3",
"date": "2020-09-13",
"amount": 65,
"quantity": 1,
},
]
and I want to join both by key (id) to get one array like this one:
"product": [
{
"id": "1000",
"code": "f230fh0g3",
"name": "Bamboo Watch",
"description": "Product Description",
"image": "bamboo-watch.jpg",
"price": 65,
"category": "Accessories",
"quantity": 24,
"orders": [
{
"id": "1000",
"productCode": "f230fh0g3",
"date": "2020-09-13",
"amount": 65,
"quantity": 1,
"customer": "David James",
"status": "PENDING"
},
{
"id": "1001",
"productCode": "f230fh0g3",
"date": "2020-05-14",
"amount": 130,
"quantity": 2,
"customer": "Leon Rodrigues",
"status": "DELIVERED"
},
]
},
{
"id": "1001",
"..."
"orders": [
{
"id": "1001",
"..."
}
]
}]
Is it possible to map these arrays in this way?
Thanks in advance
Yes, it is possible. You can use .map() and .filter() together. Assuming you have products in product variable and orders in order variable, you can compute your combined list like this:
const result = products.map(
product => ({
...product,
orders: orders.filter(
({ productID }) => productID === product.id
)
})
);
Related
I have an array like this:
Array [
Object {
"item": Object {
"amount": 1,
"price": 29.99,
"product_id": 5,
"product_name": "Calvin klein Bag",
"username": "Ester71",
},
"type": "NORMAL",
},
Object {
"item": Object {
"amount": 1,
"price": 29.99,
"product_id": 3,
"product_name": "Calvin klein Bag",
"username": "Ester71",
},
"type": "NORMAL",
},
Object {
"item": Object {
"amount": 1,
"price": 29.99,
"product_id": 5,
"product_name": "Calvin klein Bag",
"username": "Ester71",
},
"type": "NORMAL",
},
],
I want groupby product_id. But it doesnt work.
Here is an example with colors. It works, and if I remove the item in the above array then it also works, but the item have to do there.
var data = [{
"name": "jim",
"color": "blue",
"age": "22"
}, {
"name": "Sam",
"color": "blue",
"age": "33"
}, {
"name": "eddie",
"color": "green",
"age": "77"
}];
console.log(
_.chain(data)
// Group the elements of Array based on `color` property
.groupBy("color")
// `key` is group's name (color), `value` is the array of objects
.map((value, key) => ({ color: key, users: value }))
.value()
);
So how can I now groupby item.product_id ?
You can try this
const data = [
{
"item": {
"amount": 1,
"price": 29.99,
"product_id": 5,
"product_name": "Calvin klein Bag",
"username": "Ester71",
},
"type": "NORMAL",
},
{
"item": {
"amount": 1,
"price": 29.99,
"product_id": 3,
"product_name": "Calvin klein Bag",
"username": "Ester71",
},
"type": "NORMAL",
},
{
"item": {
"amount": 1,
"price": 29.99,
"product_id": 5,
"product_name": "Calvin klein Bag",
"username": "Ester71",
},
"type": "NORMAL",
},
]
const groupBy = (product) => product.item.product_id
console.log(
_.chain(data)
.groupBy(groupBy)
.map((value, key) => ({ product_id: key, products: value }))
.value()
);
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>
This question already has answers here:
How to groupBy array of objects based on properties in vanilla javascript
(2 answers)
Closed 2 years ago.
I got a json file that contains beer types like this:
{
"type": "Unifiltered",
"name": "Heineken Unfiltered",
"id": "XY",
"brand": "Heineken",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
},
My task is to group beers by brand:
My friend has a list of all the beers available in his pub, but it’s a huge mess.
He would like to see the beers grouped by brands.
My friend also told you that the Function should return an array of Brand > objects which contain the array of Beers of that Brand.
Example:
[{brand: Heineken, beers: [{...}, ...]}]"
const beers = [{
"type": "Unifiltered",
"name": "Heineken Unfiltered",
"id": "XY",
"brand": "Heineken",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
},
{
"type": "type",
"name": "name",
"id": "XY",
"brand": "EFES",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
},
{
"type": "type3",
"name": "name2",
"id": "XY",
"brand": "EFES",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
}];
var group = beers.reduce((r, a) => {
r[a. brand] = [...r[a. brand] || [], a];
return r;
}, {});
console.log("group", group);
i think its already answered here
let group = beers.reduce((r, a) => {
r[a. brand] = [...r[a. brand] || [], a];
return r;
}, {});
console.log("group", group);
Written in an easily readable format, using array.forEach() in place of shorthand functions:
let beers = [{
"type": "Unifiltered",
"name": "Heineken Unfiltered",
"id": "XY",
"brand": "Heineken",
"price": "1250",
"alcohol": "0.04",
"ingredients": [
{
"id": "XY2",
"ratio": "0.15",
"name": "salt"
},
{
"id": "XY3",
"ratio": "0.00",
"name": "sugar"
},
{
"id": "XY4",
"ratio": "0.35",
"name": "barley"
}
],
"isCan": false
}];
let brands = [];
// Loop over all beers
beers.forEach((beer) => {
// Try to find beer brand in existing list of brand
let brand = brands.filter((brand) => brand.brand === beer.brand)[0];
if(brand) {
// If we find it, push the beer onto the beer property
brand.beers.push(beer);
} else {
// If we don't find it, create a new brand and push it onto brands
brand = {
brand: beer.brand,
beers: [beer]
}
brands.push(brand);
}
});
console.log(brands);
I think Grouping JSON by values can be useful. Using the group_by function and then its is just cleaning up the answer to get what you need.
const myJSON = {
"seller1": [
{
"product": "headphones",
"price": 23,
"weight": 1
},
{
"product": "earphone",
"price": 12,
"weight": 1
},
{
"product": "iPhone",
"price": 999,
"weight": 3
},
{
"product": "ipad",
"price": 399,
"weight": 4
}
],
"seller2": [
{
"product": "headphones",
"price": 25,
"weight": 1
},
{
"product": "earphone",
"price": 10,
"weight": 1
},
{
"product": "iPhone",
"price": 949,
"weight": 2
},
{
"product": "ipad",
"price": 449,
"weight": 3
}
]
}
I need to filter myJSON from a multi-select box where, if user selects product: iPhone and product: headphones, I need to display all the products that matches iPhone and headphones. In this case, myJSON will be
const myJSON = {
"seller1": [
{
"product": "headphones",
"price": 23,
"weight": 1
},
{
"product": "iPhone",
"price": 999,
"weight": 3
}
],
"seller2": [
{
"product": "headphones",
"price": 25,
"weight": 1
},
{
"product": "iPhone",
"price": 949,
"weight": 2
},
]
}
Now if the user selects different key, price: 449, myJSON should now be empty coz there is not property price: 449 in that anymore. But, if price: 23 then,
const myJSON = {
"seller1": [
{
"product": "headphones",
"price": 23,
"weight": 1
}
]
}
So for example, if user selects 3 items with same key(product), the we should show all the three items that match these 3 items from original json. Now when he selects a different key(price), then we should only filter from the previous result.
Any suggestion on how to implement this is much appreciated.
Suppose I have the following json file and I would like to return the 'existing.primaryBundle.products' array preferrably with lodash:
{
"existing": {
"hasPlatinum": false,
"primaryBundle": {
"id": "2008",
"name": "TV - Entertainment, Sport",
"products": [
{
"name": "Entertainment",
"id": "100",
"price": 2600,
"gifted": false
},
{
"name": "Sport",
"id": "107",
"price": 2500,
"gifted": false,
"swappableProducts": [
{
"name": "Movies",
"id": "105",
"price": 2000,
"gifted": false
}
]
}
]
},
"extrasBundle": {
"id": "131",
"name": "Optional Extras - MUTV (Sports), LFCTV (Sports), Chelsea TV (Sports)",
"products": [
{
"name": "MUTV (Sports)",
"id": "665",
"price": 0,
"gifted": false
},
{
"name": "LFCTV (Sports)",
"id": "666",
"price": 0,
"gifted": false
},
{
"name": "Chelsea TV (Sports)",
"id": "667",
"price": 0,
"gifted": false
}
]
}
}
}
I have tried lodash and use this statement:
list2 = _.pick(existing,'primaryBundle.products')
But this returns an error and not the wanted result. How can I select this products array?
you could use _.get(nameOfObject, 'existing.primaryBundle.products') of course you would need to name your object like I've done below with sampleObject;
check out the lodash docs too
const sampleObject = {
"existing": {
"hasPlatinum": false,
"primaryBundle": {
"id": "2008",
"name": "TV - Entertainment, Sport",
"products": [{
"name": "Entertainment",
"id": "100",
"price": 2600,
"gifted": false
}, {
"name": "Sport",
"id": "107",
"price": 2500,
"gifted": false,
"swappableProducts": [{
"name": "Movies",
"id": "105",
"price": 2000,
"gifted": false
}]
}]
},
"extrasBundle": {
"id": "131",
"name": "Optional Extras - MUTV (Sports), LFCTV (Sports), Chelsea TV (Sports)",
"products": [{
"name": "MUTV (Sports)",
"id": "665",
"price": 0,
"gifted": false
}, {
"name": "LFCTV (Sports)",
"id": "666",
"price": 0,
"gifted": false
}, {
"name": "Chelsea TV (Sports)",
"id": "667",
"price": 0,
"gifted": false
}]
}
}
}
console.log(_.get(sampleObject, 'existing.primaryBundle.products'));
The main reason why it returns an error is because existing is not a global scoped object, you have to assign object to some variable like const obj = {...} and then pass the parameter to _pick method as obj.existing, yet I don't see a reason to use lodash in here, you can just reference the path to that object directly.
I've an array like the one below and I'm trying to sort the items in the array by its price using lodash, but I don't see it working. Please let me know what is wrong here, as per the lodash documentation it will take an array and should return the sorted array.
My data
var items= [
{
"total": 11,
"productGroup": {
"_id": "5834754f0acc770ce14b1378",
"name": "Auto Biography",
"description": "Yum",
"type": "book"
},
"_id": "58791af46c698c00475e7f41",
"price": 200,
"sold": 0
},
{
"total": 11,
"productGroup": {
"_id": "5834754f0acc770ce14b1378",
"name": "Science Fiction",
"description": "Yum",
"type": "book"
},
"_id": "58791af46c698c00475e7f41",
"price": 120,
"sold": 0
},
{
"total": 11,
"productGroup": {
"_id": "5834754f0acc770ce14b1378",
"name": "Language",
"description": "Yum",
"type": "book"
},
"_id": "58791af46c698c00475e7f41",
"price": 125,
"sold": 0
},
{
"total": 11,
"productGroup": {
"_id": "5834754f0acc770ce14b1378",
"name": "Fiction",
"description": "Yum",
"type": "book"
},
"_id": "58791af46c698c00475e7f41",
"price": 300,
"sold": 0
}
]
Sort code
items = _.sortBy(items, item=>{return item.price});
Most likely you're using an older version of Lodash. It works with 4.17.2 as demonstrated below.
var items = [
{
"_id": "58791af46c698c00475e7f41",
"price": 200
},
{
"_id": "58791af46c698c00475e7f41",
"price": 120
},
{
"_id": "58791af46c698c00475e7f41",
"price": 125
},
{
"_id": "58791af46c698c00475e7f41",
"price": 300
}
];
var results = _.sortBy(items, item => item.price);
console.log(results);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
According to the source code, the second argument should be an array of iteratees. To fix the problem you need to put your anonymous function inside an array, e.g.
items = _.sortBy(items, [item=>{return item.price}]);