【问题标题】:Add values to object in JS when using groupBy使用 groupBy 时向 JS 中的对象添加值
【发布时间】:2019-10-30 03:46:21
【问题描述】:

当两个项目具有相同的typeId 时,我正在使用mapValuesgroupBy 分组并创建keys

例如原始数据是

{
    "Name": "One",
    "typeId": 1
},
{
    "Name": "Two",
    "typeId": 2
},
{
    "Name": "One Two",
    "typeId": 1
},
{
    "Name": "Three",
    "typeId": 3
},
{
    "Name": "Three Two",
    "typeId": 3
}

通过使用groupBy,我将具有匹配typeIdomit 的对象分组为来自`objects as...的typeId 值...

const GroupedTypes = Object.entries(
   _.mapValues(_.groupBy(data, 'typeID'), rlist =>
      rlist.map(type => _.omit(type, 'typeID'))
   )
);

按预期返回...

[
    "1",
    [
      {
        "Name": "One",
      },
      {
        "Name": "One Two",
      }
    ]
  ],
  [
    "2",
    [
      {
        "Name": "Two",
      }
    ]
  ],
  [
    "3",
    [
      {
        "Name": "Three",
      }
    ],
    [
      {
        "Name": "Three Two",
      }
    ]
]

但是,我还想从第一个 0 对象的值 Name 中为 Name 添加一个对象。因此最终得到类似..

[
    "1",
    "One",
    [
      {
        "Name": "One",
      },
      {
        "Name": "One Two",
      }
    ]
],
[
    "2",
    "Two",
    [
      {
        "Name": "Two",
      }
    ]
],
[
    "3",
    "Three",
    [
      {
        "Name": "Three",
      }
    ],
    [
      {
        "Name": "Three Two",
      }
    ]
]

我一直在查看lodash 文档,但找不到有效的方法。我怎样才能做到这一点?

【问题讨论】:

  • lodash 有必要吗?使用内置的 Javascript 方法很容易做到这一点

标签: javascript arrays object ecmascript-6 lodash


【解决方案1】:

您可以使用reduce 根据typeId 对项目进行分组:

const input=[{"Name":"One","typeId":1},{"Name":"Two","typeId":2},{"Name":"One Two","typeId":1},{"Name":"Three","typeId":3},{"Name":"Three Two","typeId":3}]

const merged = input.reduce((acc, { Name, typeId }) => {
  acc[typeId] = acc[typeId] || [ typeId, Name, []];
  acc[typeId][2].push({ Name });
  return acc;
}, {})

console.log(Object.values(merged))

您需要创建一个累加器对象,其中每个 typeId 作为键,输出中需要的数组作为其值。如果该键不存在,则添加带有[ typeId, Name, []] 的键作为值。这样,第一项的Name 将在输出中。这是累加器/merged 的样子:

{
      "1": [1, "One", [{ "Name": "One" }, { "Name": "One Two" }]],
      "2": [2, "Two", [{ "Name": "Two" }]],
      "3": [3, "Three", [{ "Name": "Three" }, { "Name": "Three Two" }]]
}

然后使用 Object.values() 将这个对象的值作为一个数组获取

【讨论】:

  • 谢谢阿迪加。另一个回答了我关于groupBy 的问题,但是如上所述,这可能是实现目标的更好方法。
【解决方案2】:

只需添加另一个mapsplice

const FilterGuests = [{
  "Name": "One",
  "typeId": 1
}, {
  "Name": "Two",
  "typeId": 2
}, {
  "Name": "One Two",
  "typeId": 1
}, {
  "Name": "Three",
  "typeId": 3
}, {
  "Name": "Three Two",
  "typeId": 3
}];

const GroupedTypes = Object.entries(
  _.mapValues(_.groupBy(FilterGuests, 'typeId'), rlist =>
    rlist.map(roomType => _.omit(roomType, 'typeId'))
  )
).map(e => {
  e.splice(1, 0, e[1][0].Name);
  return e;
});

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

【讨论】:

    【解决方案3】:

    使用_.map() 而不是_.mapValues(),它也适用于对象,并返回一个数组。在地图的回调中,从第二个参数中获取组键,取第一个元素Name,并以请求的格式返回一个数组:

    const FilterGuests = [{"Name":"One","typeId":1},{"Name":"Two","typeId":2},{"Name":"One Two","typeId":1},{"Name":"Three","typeId":3},{"Name":"Three Two","typeId":3}];
    
    const GroupedTypes = _.map(
      _.groupBy(FilterGuests, 'typeId'), 
      (rlist, key) =>
      [
        key, 
        _.get(rlist, '[0].Name'), 
        rlist.map(roomType => _.omit(roomType, 'typeId'))
      ]
    )
    
    console.log(GroupedTypes);
    .as-console-wrapper { max-height: 100% !important; top: auto; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-26
      • 2019-05-26
      • 2021-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多