Объединить спецификации c свойств объектов вместе с JavaScript - PullRequest
0 голосов
/ 31 января 2020

Итак, у меня есть массив таких объектов:

[
  {
    name: "Joe Smith",
    job: "Janitor",
    age: 35,
    id: "3421"
  },
  {
    name: "George Henderson",
    job: "CEO",
    age: 43,
    id: "5098"
  },
  {
    name: "Joe Smith",
    job: "Cook",
    age: 35,
    id: "3421"
  },
  {
    name: "Sam Doe",
    job: "Technician",
    age: 22,
    id: "1538"
  },
  {
    name: "Joe Smith",
    job: "Dishwasher",
    age: 35,
    id: "3421"
  } 
]

Как видите, у Джо Смита есть три задания. То, что я хочу сделать, это объединить все его работы в один объект, например, так:

{
   name: "Joe Smith",
   job: "Janitor, Cook, Dishwasher",
   age: 35,
   id: "3421"
}

Я бы хотел сделать это с любым человеком, который имеет несколько рабочих мест. Кроме того, может быть несколько человек с одним и тем же именем, поэтому было бы лучше идентифицировать людей по их идентификатору, а не по имени.

Как мне go поступить так? Использование библиотеки, такой как Loda sh, прекрасно, если она упрощает код, но я не могу придумать более простой способ, чем перебирать массив, но это может стать сложным.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 31 января 2020

С loda sh вы можете сгруппировать массив и отобразить нужные свойства.

var data = [{ name: "Joe Smith", job: "Janitor", age: 35, id: "3421" }, { name: "George Henderson", job: "CEO", age: 43, id: "5098" }, { name: "Joe Smith", job: "Cook", age: 35, id: "3421" }, { name: "Sam Doe", job: "Technician", age: 22, id: "1538" }, { name: "Joe Smith", job: "Dishwasher", age: 35, id: "3421" }],
    result = _(data)
        .groupBy('id')
        .map(array => ({ ...array[0], job: _.join(_.map(array, 'job'), ", ") }))
        .value();

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
3 голосов
/ 31 января 2020

Используя reduce для перебора массива для создания нового, и просто проверьте, вставлен ли идентификатор, затем объедините задание, в противном случае вставьте новый объект:

const arr = [
  { name: "Joe Smith", job: "Janitor", age: 35, id: "3421" },
  { name: "George Henderson", job: "CEO", age: 43, id: "5098" },
  { name: "Joe Smith", job: "Cook", age: 35, id: "3421" },
  { name: "Sam Doe", job: "Technician", age: 22, id: "1538" },
  { name: "Joe Smith", job: "Dishwasher", age: 35, id: "3421" } 
]

const result = arr.reduce((acc, cur) => {
    const duplicate = acc.find(e => e.id == cur.id)
    
    if (duplicate) {
	duplicate.job += ', ' + cur.job
    } else {
	acc.push(cur)
    }

    return acc
}, [])

console.log(result)
1 голос
/ 31 января 2020

Я бы предложил использовать временный Map, чтобы избежать необходимости повторять каждый раз, чтобы определить, является ли имя дубликатом (например, с find).

Кроме того, кажется, что лучше использовать пусть множественные значения job будут помещены в массив:

let data = [{name: "Joe Smith",job: "Janitor",age: 35,id: "3421"},{name: "George Henderson",job: "CEO",age: 43,id: "5098"},{name: "Joe Smith",job: "Cook",age: 35,id: "3421"},{name: "Sam Doe",job: "Technician",age: 22,id: "1538"},{name: "Joe Smith",job: "Dishwasher",age: 35,id: "3421"}];

let map = new Map(data.map(({name, job, age, id}) => [id, { name, job: [], age, id}]));
data.forEach(o => map.get(o.id).job.push(o.job));
let result = Array.from(map.values());

console.log(result);

Если вы действительно хотите объединить массивы заданий в виде значений, разделенных запятыми, тогда примените к ним join(", "), но я бы go для массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...