【问题标题】:Underscore/Lodash: Group object by substring of key下划线/Lodash:按键的子字符串对对象进行分组
【发布时间】:2019-09-30 09:59:31
【问题描述】:

我正在尝试根据对象键的子字符串将对象分组为更有条理的结构。

下面是我传递的对象的示例:

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"}]}

我尝试在 Lodash 和 Underscore.js 中使用 groupBy 对对象进行分组,但没有任何运气。

在下划线内我可以使用以下代码(请注意,这在 Lodash 中不起作用,因为我似乎无法获取 Object Key 的值:

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"}]}

但是我想将对象键保留在我的输出中,并且您可以看到它正在删除它们。

我正在做的事情可能吗?

抱歉,如果这没有意义或已经被问过,但我一直在寻找解决方案的时间超出了我的预期,并且开始没有想法了。

感谢您抽出宝贵时间阅读本文,如有任何问题,请随时提出!

【问题讨论】:

  • 顺便说一句,您的组必须是对象,而不是数组。
  • 您的预期输出无效。
  • 为此道歉,一定是在写问题时忽略了我的输出结构。

标签: javascript underscore.js lodash


【解决方案1】:

Lodash 的_.groupBy() 用唯一的值调用 iteratee,另外 groupBy 的结果是数组的对象,而不是你需要的对象的对象。

解决方案 1 - lodash:

您可以使用_.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>

【讨论】:

    【解决方案2】:

    您可以获取对象的条目并通过该键构建一个新键和组。

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

    【讨论】:

    • 完美!谢谢你,这让我头疼了一段时间,数据的结构都应该是这样的。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 2021-01-06
    • 2018-05-13
    相关资源
    最近更新 更多