сначала groupBy, затем сортировать массив по имени с помощью lodash? - PullRequest
0 голосов
/ 27 июня 2018

У меня есть JSON в виде:

data = { 
    "1": {"name": "eve", "type": "sergeant", "age": 22},
    "2": {"name": "bob", "type": "sergeant", "age": 33},
    "3": {"name": "bats", "type": "private", "age": 90},
    "4": {"name": "carol", "type": "captain", "age": 50},
    "5": {"name": "noogle", "type": "sergeant", "age": 34},
    "6": {"name": "good", "type": "sergeant", "age": 47},
    "7": {"name": "alice", "type": "private", "age": 34}
}

Как я могу groupBy их type, а затем внутри каждого типа они сортируются по имени в порядке возрастания?

Я пытался сделать это с:

let grouped = _.groupBy(Object.keys(data), function(id) {
    return data[id].type;
});

Что даст мне что-то вроде:

{
    "sergeant": ["1", "2", "5", "6"],
    "private": ["3", "7"],
    "captain": ["4"]
}

Но когда я пытаюсь sortBy, он дает мне тот же объект, что и выше:

_.map(Object.keys(grouped), function(type_name) {
    grouped[type_name] = _.sortedBy(grouped[type_name], function(id) {
        return data[id].name;
    });
});

Как мне отсортировать массив после того, как я сгруппировал объекты вместе? Есть ли способ, которым я могу чисто соединить groupBy и sortBy вместе вместо разделения логики, как у меня выше?

1 Ответ

0 голосов
/ 27 июня 2018

Вы можете использовать метод _.mapValues для сортировки каждой группы после того, как вы сгруппировали их, используя _.groupBy. Просто возьмите каждое значение и верните отсортированную версию в функции обратного вызова _.mapValues.

Пример:

data = { 
    "1": {"name": "eve", "type": "sergeant", "age": 22},
    "2": {"name": "bob", "type": "sergeant", "age": 33},
    "3": {"name": "bats", "type": "private", "age": 90},
    "4": {"name": "carol", "type": "captain", "age": 50},
    "5": {"name": "noogle", "type": "sergeant", "age": 34},
    "6": {"name": "good", "type": "sergeant", "age": 47},
    "7": {"name": "alice", "type": "private", "age": 34}
}

console.log(_.mapValues(_.groupBy(data, "type"), v => _.sortBy(v, "name")))
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>

Или, если вы просто хотите сгруппировать и отсортировать ключи, или сгруппировать и отсортировать ключи / значения, вы можете использовать тот же подход, хотя это не так просто для глаз:

data = { 
    "1": {"name": "eve", "type": "sergeant", "age": 22},
    "2": {"name": "bob", "type": "sergeant", "age": 33},
    "3": {"name": "bats", "type": "private", "age": 90},
    "4": {"name": "carol", "type": "captain", "age": 50},
    "5": {"name": "noogle", "type": "sergeant", "age": 34},
    "6": {"name": "good", "type": "sergeant", "age": 47},
    "7": {"name": "alice", "type": "private", "age": 34}
}

// If all you want are grouped and sorted keys:
console.log(_.mapValues(_.groupBy(_.keys(data), k => data[k].type), v => _.sortBy(v, i => data[i].name)))

// Or for grouped and sorted keys and values:
console.log(_.mapValues(_.groupBy(_.keys(data), k => data[k].type), v => _.sortBy(v, i => data[i].name).map(k => ({[k]: data[k]}))))
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
...