Объединить объект с тем же значением - PullRequest
1 голос
/ 08 марта 2020

У меня есть массив, как показано ниже:

var array = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]

Я хотел бы иметь вывод как:

array = [{name: 'abc', age: [17, 89]}, {name: 'cde', age: 20}]

Как этого добиться? Я пробовал много решений, таких как, например:

var result = _(array)
      .groupBy('name')
      .map(_.spread(_.assign))
      .value();

, но это не то, что я хочу, потому что я хотел бы иметь массив значений age.

Ответы [ 5 ]

2 голосов
/ 08 марта 2020

попробуйте

const data  = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]
         
const groupBy = (arr) => data.reduce((acc, ele)=>( (acc[ele.name] = acc[ele.name] || []).push(ele), acc),{})
const displayAge= v => v.length>1?v.map(e=>e.age):v[0].age

console.log(Object.entries(groupBy(data)).map(([name, v])=>({name, age: displayAge(v)})))
1 голос
/ 08 марта 2020

Вы можете создать карту (с постоянным временем поиска), а затем преобразовать ее в массив. Не самое красивое решение, но определенно эффективное с точки зрения сложности (линейное).

const array = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]

const m = new Map();
array.map(x => {
    if (!m.has(x.name)) {
        m.set(x.name, []);
    }
    m.get(x.name).push(x.age);
});

console.log(Array.from(m).map(
    (x) => Object.assign({'name': x[0], 'age': x[1]})));
0 голосов
/ 08 марта 2020

Было бы проще, если бы вы всегда указывали возраст как массив, а не как число, когда присутствует только одно значение.

const array = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]
const newArray = array.reduce((arr, i) => {
    const inArray = arr.findIndex(a => a.name === i.name);
    if (inArray < 0) arr.push(i);
    else {
        if (Array.isArray(arr[inArray].age)) {
            arr[inArray].age.push(i.age);
        } else {
            arr[inArray].age = [arr[inArray].age, i.age];
        }
    }
    return arr;
}, [])

console.log(newArray);
0 голосов
/ 08 марта 2020

А как же:

var result = array.forEach(a => {
    let similar = array.filter(b => b.name == a.name).map(c => c.age);
    a.age = similar.length > 1 ? similar : a.age;
}).filter((d,e) => array.indexOf(d) == e);
0 голосов
/ 08 марта 2020

Ну, я не понимаю, почему вы не используете циклы или что-то еще ... Вы не указали формат, поэтому вот мой код в ваниле js:

var array = [{name: 'abc', age: 17}, {name: 'cde', age: 20}, {name: 'abc', age: 89}]

for (var i = 0; i < array.length; i++) {
  for (var j = i + 1; j < array.length; j++) {
    if (array[i].name == array[j].name) {
      if (Array.isArray(array[i].age)) {
        array[i].age.push(array[j].age)
      } else {
        var arAge = [array[i].age, array[j].age];
        array[i].age = arAge;
      }
      array.splice(j,1);
      j--;
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...