Добавить значения к объекту в JS при использовании groupBy - PullRequest
0 голосов
/ 16 июня 2019

Я использую mapValues и groupBy для группировки и создания keys, когда два элемента имеют одинаковые typeId.

Например, исходные данные

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

и с помощью groupBy я группирую объекты с соответствующими typeId и omit значением typeId из `объектовas ...

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

Однако я также хотел бы добавить объект для Name из значения Name впервый 0 объект.Таким образом, получилось что-то вроде ..

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

Я просматривал документацию lodash и не могу найти метод, который работает.Как мне этого добиться?

Ответы [ 3 ]

3 голосов
/ 16 июня 2019

Вы можете использовать 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(), чтобы получить только значения этого объекта в виде массива

1 голос
/ 16 июня 2019

Просто добавьте еще map с splice.

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>
0 голосов
/ 16 июня 2019

Используйте _.map(), а не _.mapValues(), который также работает с объектами и возвращает массив. В обратном вызове карты получите ключ группы из 2-го параметра, возьмите 1-й элемент 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>
...