Count total with two criterias using Lodash

2019-08-12 16:59发布

问题:

I can't figure out how I can count the total devices based on location and unique serial number.

{
"dates": [
    {
        "date": "Sep 1, 2014",
        "devices": [
            {
                "model": "Canon",
                "location": "Chicago",
                "serialNum": "abc123"
            },
            {
                "model": "Canon",
                "location": "Chicago",
                "serialNum": "xyz456"
            },
            {
                "model": "HP",
                "location": "New York",
                "serialNum": "123456"
            },
            {
                "model": "Brother",
                "location": "Chicago",
                "serialNum": "DEF777"
            }
        ]
    },
    {
        "date": "Sep 2, 2014",
        "devices": [
            {
                "model": "Canon",
                "location": "Chicago",
                "serialNum": "abc123"
            },
            {
                "model": "Canon",
                "location": "Chicago",
                "serialNum": "xyz456"
            }
        ]
    },
    {
        "date": "Sep 3, 2014",
        "devices": [
            {
                "model": "Canon",
                "location": "Chicago",
                "serialNum": "xyz456"
            },
            {
                "model": "Canon",
                "location": "Chicago",
                "serialNum": "stu789"
            },
            {
                "model": "Epson",
                "location": "NewYork",
                "serialNum": "123456"
            },
            {
                "model": "Epson",
                "location": "NewYork",
                "serialNum": "555555"
            },
            {
                "model": "HP",
                "location": "NewYork",
                "serialNum": "987654"
            }
        ]
    }
]

}

I would like to capture the total number of unique devices per location

Chicago - 4
New York - 3

回答1:

Here it is, in a single expression with lodash chaining syntax. The short version is you get all devices into one massive list, then you group them by location, then for each location eliminate the duplicate ids, then count the devices.

_(dates) //Begin chain
    .pluck("devices") //get the device list for each date
    .flatten() //combine all device lists into a master list
    .groupBy("location") //group into an object of {"location": [devices]} pairs
    .mapValues(function (devicesForLocation) { //replaces [devices] with a count of number of unique serial numbers
        return _(devicesForLocation) //Begin chain
            .pluck("serialNum") //get the serial number for each device
            .uniq() //remove the duplicate serial numbers
        .value() //End chain
        .length; // get the count of unique serial numbers
    }) // result is an object of {"location": countOfUniqueDevices} pairs
.value() //End chain

The final result is an object of the form: {"New York": 1, "NewYork": 3, "Chicago": 4}, though you could add another statement to print that out in string form, obviously.

I'd encourage you to run through this step-by-step to see the result of each step and understand what it's doing.