Подчеркивание / Lodash: группировка объекта по подстроке ключа - PullRequest
2 голосов
/ 13 мая 2019

Я пытаюсь сгруппировать объект в более организованную структуру на основе подстроки ключа объекта.

Ниже приведен пример объекта, который я передаю:

var data = {
  "summ_example_1": {
    "value": 40464.284237
  },
  "summ_example_number_2": {
    "value": 39260.605837
  },
  "in_process_example_1": {
    "count": 10,
    "value": 10
  },
  "in_process_example_2": {
    "count": 12,
    "value": 12.5
  },
  "in_process_example_3": {
    "count": 0,
    "value": 0
  },
  "awaiting_example_1": {
    "count": 17,
  },
  "awaiting_example_2": {
    "count": 51,
  }
}

Вывод, который я хочу получить:

{ summ:
    ["summ_example_1": {"value": 40464.284237},
     "summ_example_number_2": {"value": 39260.605837}],
  in:
    ["in_process_example_1": {"count": 10, "value": 10},
     "in_process_example_2": {"count": 12, "value": 12.5},
     "in_process_example_3": {"count": 0, "value": 0}],
  awaiting:
    ["awaiting_example_1": {"count": 17},
     "awaiting_example_2": {"count": 51"}]}

Я попытался сгруппировать объект с помощью groupBy как в Lodash, так и в Underscore.js без какой-либо удачи.

В нижнем подчеркивании я могу использовать следующеекод (Обратите внимание, что это не работает в Lodash, так как я не могу получить значение ключа объекта:

var grouped = _.groupBy(data, function(val, key){
    return key.substr(0, key.indexOf('_'));
});

, который выдает следующий вывод:

{ summ:
    [{"value": 40464.284237},
     {"value": 39260.605837}],
  in:
    [{"count": 10, "value": 10},
     {"count": 12, "value": 12.5},
     {"count": 0, "value": 0}],
  awaiting:
    [{"count": 17},
     {"count": 51"}]}

Однако яхочу сохранить ключи объекта внутри моего вывода, и, как вы можете видеть, он удаляет их.

Возможно ли то, что я делаю?

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

Спасибо, что нашли время, чтобы прочитать это, и, пожалуйста, не стесняйтесь задавать любые вопросы.stions!

Ответы [ 2 ]

4 голосов
/ 13 мая 2019

Вы можете взять записи объекта и построить новый ключ и группу по этому ключу.

var data = { summ_example_1: { value: 40464.284237 }, summ_example_number_2: { value: 39260.605837 }, in_process_example_1: { count: 10, value: 10 }, in_process_example_2: { count: 12, value: 12.5 }, in_process_example_3: { count: 0, value: 0 }, awaiting_example_1: { count: 17 }, awaiting_example_2: { count: 51 } },
    result = Object.entries(data).reduce((r, [k, v]) => {
        var key = k.replace(/_.*$/, '') ;
        (r[key] = r[key] || {})[k] = v;
        return r;
    }, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 13 мая 2019

Lodash _.groupBy() вызывает итератора с единственным значением, кроме того, результатом groupBy является объект массивов, а не объект объектов, которые вам нужны.

Раствор 1 - Лодаш:

Вы можете создать функцию с _.flow(), которая отображает каждый объект для включения ключа группы (например, summ), и они объединяют их вместе:

const { flow, map, partialRight: pr, spread, merge } = _

const fn = flow(
  pr(map, (v, k) => ({ [k.split('_')[0]]: { [k]: v }})), // format each object to have the group key - summ for example
  spread(merge) // merge all objects together
)

const data = { summ_example_1: { value: 40464.284237 }, summ_example_number_2: { value: 39260.605837 }, in_process_example_1: { count: 10, value: 10 }, in_process_example_2: { count: 12, value: 12.5 }, in_process_example_3: { count: 0, value: 0 }, awaiting_example_1: { count: 17 }, awaiting_example_2: { count: 51 } };

const result = fn(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Решение 2 - lodash / fp

Поскольку lodash / fp _.map() не передает ключ итерируемому, используйте _.pairs() для создания кортежа [key, value]. Сопоставьте кортежи с ключом группы и объедините их все вместе.

const { flow, toPairs, map, mergeAll } = _

const fn = flow(
  toPairs,
  map(([k, v]) => ({ [k.split('_')[0]]: { [k]: v }})),
  mergeAll
)

const data = { summ_example_1: { value: 40464.284237 }, summ_example_number_2: { value: 39260.605837 }, in_process_example_1: { count: 10, value: 10 }, in_process_example_2: { count: 12, value: 12.5 }, in_process_example_3: { count: 0, value: 0 }, awaiting_example_1: { count: 17 }, awaiting_example_2: { count: 51 } };

const result = fn(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...