How do I sort with Lodash sortBy? - javascript

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}]);

Related

Append array to atribute of another array (javascript) [duplicate]

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
)
})
);

How do I solve this task in javascript? [duplicate]

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.

Complex procedures with JSON and Javascript (ES6)

Alright, I have to this JSON:
https://gist.github.com/pedroapfilho/c1673be24dfdb36133149b4edfc8c2bd
and:
1 - List the categories alphabetically (and filter to show unique values)
2 - Arrange this array in ascending order taking as parameter the sum of the subscription price
Thanks a lot !
Give this a try.
let json = [{
"id": "9b565b11-7311-5b5e-a699-97873dffb361",
"name": "Voice Report",
"description": "Calls reporting and analytics of your calls.",
"categories": ["Voice Analytics", "Reporting", "Optimization"],
"subscriptions": [{
"name": "Trial",
"price": 0
},
{
"name": "Professional",
"price": 3500
}
]
},
{
"id": "470fedc5-489e-5acb-a200-c85adaa18356",
"name": "Power Dialer",
"description": "Auto dialer that will help increase your connect rates and talk time.",
"categories": ["Dialer"],
"subscriptions": [{
"name": "Trial",
"price": 0
},
{
"name": "Professional",
"price": 4500
},
{
"name": "Premium",
"price": 6000
}
]
},
{
"id": "52714d80-e3c4-5593-b9a3-e2ff484be372",
"name": "Smart Text",
"description": "Use SMS to help you communicate with your customers.",
"categories": ["Channels"],
"subscriptions": [{
"name": "Trial",
"price": 0
}]
},
{
"id": "8d68c357-59e6-505a-b0e1-4953196b14df",
"name": "Customer Chat",
"description": "Improve your call center with live chat support.",
"categories": ["Channels"],
"subscriptions": [{
"name": "Trial",
"price": 0
}]
},
{
"id": "dd024ed5-efae-5785-addc-09e592066e5c",
"name": "Report Plus",
"description": "Advanced reporting with custom dashboards.",
"categories": ["Reporting"],
"subscriptions": [{
"name": "Starter",
"price": 2000
},
{
"name": "Plus",
"price": 4500
}
]
},
{
"id": "f820ad5d-32d0-5bb7-aed4-cbc74bcf0b47",
"name": "Screen Share",
"description": "Enable screen sharing between your agents and customers.",
"categories": ["Productivity"],
"subscriptions": [{
"name": "Professional",
"price": 6000
}]
},
{
"id": "7f89f001-9d7d-52f1-82cb-8f44eb1e4680",
"name": "Video Contacts",
"description": "Communicate with your customers and agents using video calls.",
"categories": ["Productivity"],
"subscriptions": [{
"name": "Trial",
"price": 0
},
{
"name": "Professional",
"price": 2500
}
]
},
{
"id": "32be8940-aeb6-5325-ae63-6497772f362a",
"name": "Agent Monitor",
"description": "More tools to monitor your agents activity.",
"categories": ["Productivity", "Management"],
"subscriptions": [{
"name": "Trial",
"price": 0
},
{
"name": "Professional",
"price": 3000
}
]
},
{
"id": "b4e7899b-07ba-55b1-9ed3-c38b878623fe",
"name": "Awesome Calls",
"description": "Tools to optimize your call center with voice analytics.",
"categories": ["Optimization", "Voice Analytics"],
"subscriptions": [{
"name": "Trial",
"price": 0
},
{
"name": "Professional",
"price": 5000
},
{
"name": "Enterprise",
"price": 10000
}
]
},
{
"id": "d8652502-f8f2-5c35-8de5-b9adfebbf4cf",
"name": "Scripted",
"description": "Help your agents communicate with customers using scripts.",
"categories": ["Productivity", "Optimization"],
"subscriptions": [{
"name": "Trial",
"price": 0
},
{
"name": "Professional",
"price": 4000
}
]
}
];
json.sort((a, b) => {
let sumA = a['subscriptions'].reduce((accumulator, current) => {
return accumulator + current['price'];
}, 0);
let sumB = b['subscriptions'].reduce((accumulator, current) => {
return accumulator + current['price'];
}, 0);
return sumA - sumB;
});
let categories = json.reduce((accumulator, current) => {
return accumulator.concat(current['categories']).filter((value, index, self) => {
return self.indexOf(value) === index;
});
}, []).sort();
console.log(json);
console.log(categories);

Filter json object in JavaScript with a combination of Union and Intersection

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.

How to return a childobject from json with lodash?

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.

Categories