【问题标题】:Merge values of objects with same keys into an array using lodash使用 lodash 将具有相同键的对象的值合并到一个数组中
【发布时间】:2021-07-14 12:34:43
【问题描述】:

我有一个如下所示的对象数组:

const childrens = [
    { orderName: "#1004" },
    { orderName: "#1006" },
    { orderName: "#1007" },
    { orderName: "#1005" },
    { deliveryDate: "25-25-25" },
    { signature: "xq" },
  ];

我希望将其转换为对象,并具有与这样的值数组相同的键值

{
  orderName: [ '#1004', '#1006', '#1007', '#1005' ],
  deliveryDate: [ '25-25-25' ],
  signature: [ 'xq' ]
}

我现在这样做的方式是使用这样的 reduce 函数

_.reduce(
    childrens,
    (acc, cur) => {
      const pairs = _.chain(cur).toPairs().flatten().value();

      if (acc[pairs[0]] === undefined) {
        acc[pairs[0]] = [pairs[1]];
      } else {
        acc[pairs[0]].push(pairs[1]);
      }

      return acc;
    },
    {},
  );

我想知道使用内置 lodash 函数是否有更简洁的方法?

【问题讨论】:

    标签: javascript node.js lodash


    【解决方案1】:

    您可以将_.mergeWith() 与数组展开一起使用。合并 2 个值时,检查第一个(a)是否仍然是 undefined(空对象),如果是,则返回包裹在数组中的第二项,如果存在,则使用数组扩展来连接它们:

    const children = [{"orderName":"#1004"},{"orderName":"#1006"},{"orderName":"#1007"},{"orderName":"#1005"},{"deliveryDate":"25-25-25"},{"signature":"xq"}];
    
    const result = _.mergeWith({}, ...children, (a, b) => 
      _.isUndefined(a) ? [b] : [...a, b]
    );
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    【讨论】:

    • 谢谢!这正是我想要的
    • 你能告诉我 lodash 如何神奇地将键分配给相关值吗?我试图在文档中阅读有关此 mergeWith 函数的信息,但不明白如何。我尝试在 mergeWith 函数中记录 a 和 b 的值,这就是我得到的,我不明白的是它们如何链接到正确的键...``` { a: undefined, b: '#1004 ' } { a: [ '#1004' ], b: '#1006' } { a: [ '#1004', '#1006' ], b: '#1007' } { a: [ '#1004', '#1006', '#1007' ], b: '#1005' } { a: undefined, b: '25-25-25' } { a: undefined, b: 'mk' } ```
    • _.mergeWith() 定制器在合并每个键的值时被调用。可以看到传递给定制器的参数((objValue, srcValue, key, object, source, stack)),第三个是关键。本质上,当香草回答这个问题时,它会迭代项目,迭代当前项目的键,并将每个键的相关值与最终对象的当前值相匹配。它只是使用定制器来决定如何处理每个值。
    【解决方案2】:

    如果你不使用 lodash,你可以像下面这样。

    const children = [
      { orderName: "#1004" },
      { orderName: "#1006" },
      { orderName: "#1007" },
      { orderName: "#1005" },
      { deliveryDate: "25-25-25" },
      { signature: "xq" },
    ];
    
    const output = children.reduce((a, b) => {
      const key = Object.keys(b)[0];
      if (!a[key]) {
        a[key] = [b[key]];
      } else {
        a[key].push(b[key]);
      }
      return a;
    }, {});
    
    console.log(output);

    【讨论】:

      【解决方案3】:

      这样的东西可以在现代 JS 平台上运行(额外的好处,你不需要 lodash 来使用reduce)。本质上:

      • 循环遍历childrens 中的每个项目
      • 获取该对象的密钥
      • 循环遍历键
        • 如果结果没有该键,则将其设置为空数组
        • 将键的值推送到结果上的相关数组
      const desiredOutput = childrens.reduce(
        (acc, current) => {
          const keys = Object.keys(current);
          keys.forEach(key => {
            if (!acc[key]) {
              acc[key] = [];
            }
            acc[key].push(current[key]);
          });
          return acc;
        },
        {}
      );
      

      【讨论】:

        【解决方案4】:

        您可以使用 reduceObject.entries 使用 vanilla JS 简单地获得结果

        (acc[prop] = acc[prop] ?? []).push(value);
        

        const childrens = [
          { orderName: "#1004" },
          { orderName: "#1006" },
          { orderName: "#1007" },
          { orderName: "#1005" },
          { deliveryDate: "25-25-25" },
          { signature: "xq" },
        ];
        
        const result = childrens.reduce((acc, curr) => {
          const [[prop, value]] = Object.entries(curr);
          (acc[prop] = acc[prop] ?? []).push(value);
          return acc;
        }, {});
        
        console.log(result);

        【讨论】:

          猜你喜欢
          • 2021-10-16
          • 1970-01-01
          • 2021-04-09
          • 2020-09-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-22
          • 1970-01-01
          相关资源
          最近更新 更多