javascript: объединить объекты с одним и тем же главным ключом - PullRequest
1 голос
/ 12 апреля 2020

Как мне объединить объекты с одним и тем же ключом, скажем:

{id: 222, date: 'apr 1', todo: 'nothing' },
{id: 222, date: 'apr 2', todo: '' },
{id: 222, date: 'apr 3', todo: 'swim' },
{id: 222, date: 'apr 4', todo: 'run' },
{id: 222, date: 'apr 1', todo : ''},
{id: 222, date: 'apr 2', todo : 'jump'},
{id: 222, date: 'apr 3', todo : ''},
{id: 222, date: 'apr 4', todo : ''}

результат должен быть

{id: 222,
date1: 'apr 1', todo1: 'nothing', 
date2: 'apr 2', todo2: 'jump',
date3: 'apr 3', todo3: 'swim',
date4: 'apr 4', todo4: 'run'
}

Мне удалось как-то объединить его, но вместо этого, я получил этот результат ....

{id:222, date1: 'apr 1', todo1: 'nothing',
date2: 'apr 2', todo2: '',
date3: 'apr 3', todo3: 'swim',
date4: 'apr 4', todo4: 'run',
date5: 'apr 1', todo5: '',
date6: 'apr 2', todo6: 'jump'
date7: 'apr 3', todo7: '',
date8: 'apr 4', todo8: ''
}

Вот мой код:

var result = Object.values(temp.reduce((r, { id, date, todo }) => {
if (r[id]){
    r[id].payload['date' + r[id].index] = date;
    r[id].payload['todo' + r[id].index] = todo;
    r[id].index++;
} 
else r[id] = { index: 2, payload: { id, date, todo } };
   return r;
}, {}))
.map(({ payload }) => payload);

Ответы [ 3 ]

1 голос
/ 12 апреля 2020

Попробуйте использовать reduce метод для группировки по date свойству:

let arr = [
    { id: 222, date: 'apr 1', todo: 'nothing' },
    { id: 222, date: 'apr 2', todo: '' },
    { id: 222, date: 'apr 3', todo: 'swim' },
    { id: 222, date: 'apr 4', todo: 'run' },
    { id: 222, date: 'apr 1', todo: '' },
    { id: 222, date: 'apr 2', todo: 'jump' },
    { id: 222, date: 'apr 3', todo: '' },
    { id: 222, date: 'apr 4', todo: '' }
];
const result = arr.reduce((a, { id, date, todo}) => {
    a[date] = a[date] || { id, date, todo};
    if (a[date].todo.length === 0 )
        a[date].todo = todo;
    return a;
}, {})

console.log(Object.values(result));

или вы можете хранить все todo в массиве:

const result = arr.reduce((a, { id, date, todo}) => {
    a[date] = a[date] || { id, date, todo:[]};
    a[date].todo.push(todo);
    return a;
}, {})

ОБНОВЛЕНИЕ:

Обновлено вывод:

let arr = [
    { id: 222, date: 'apr 1', todo: 'nothing' },
    { id: 222, date: 'apr 2', todo: '' },
    { id: 222, date: 'apr 3', todo: 'swim' },
    { id: 222, date: 'apr 4', todo: 'run' },
    { id: 222, date: 'apr 1', todo: '' },
    { id: 222, date: 'apr 2', todo: 'jump' },
    { id: 222, date: 'apr 3', todo: '' },
    { id: 222, date: 'apr 4', todo: '' }
];

const result = arr.reduce((a, { id, date, todo}) => {
    a[id] = a[id] || { id };
    let key = date.split(' ').pop();
    a[id]['date' + key] = date;
    a[id]['todo' + key] = (todo.length > 0) ? todo : a[id]['todo' + key];
    return a;
}, {})
console.log(Object.values(result));

ОБНОВЛЕНИЕ 1:

let arr = [
    { id: 222, date: 'apr 1', todo: 'nothing' },
    { id: 222, date: 'apr 2', todo: '' },
    { id: 222, date: 'apr 3', todo: 'swim' },
    { id: 222, date: 'apr 4', todo: 'run' },
    { id: 222, date: 'apr 1', todo: '' },
    { id: 222, date: 'apr 2', todo: 'jump' },
    { id: 222, date: 'apr 3', todo: '' },
    { id: 222, date: 'apr 4', todo: '' }
];

const groupedById = Object.values(arr.reduce((a, { id, date, todo}) => {
    a[id] = a[id] || { id };
    a[id][date] = a[id][date] || {date};
    if (todo.length > 0 && !a[id][date]['todo'])
        a[id][date]['todo'] = todo;
    return a;
}, {}));

const result = groupedById.reduce((a, {id, ...rest})=> {
    let count = 0;
    for (const key in rest) {
        count++;
        a['date' + count] =rest[key].date;
        a['todo' + count] =rest[key].todo;
    }
    a[id] = id;
    return a;
}, {})

console.log(result);
0 голосов
/ 12 апреля 2020

Этого можно достичь с помощью sort(), filter() и reduce():

let arr=[{id:222,date:"apr 1",todo:"nothing"},{id:222,date:"apr 2",todo:""},{id:222,date:"apr 3",todo:"swim"},{id:222,date:"apr 4",todo:"run"},{id:222,date:"apr 1",todo:""},{id:222,date:"apr 2",todo:"jump"},{id:222,date:"apr 3",todo:""},{id:222,date:"apr 4",todo:""}];

let res = arr.sort((a, b) => {
  return (a.date > b.date) ? 1 : -1
}).filter(el => {
  return el.todo
}).reduce((acc,el,idx) => {
    !("id" in acc) && (acc.id = 222)
    return el.id === 222 ? Object.assign(acc, {["date" + (idx+1)] : el.date, ["todo" + (idx+1)] : el.todo}) : acc
},{})

console.log(res)
0 голосов
/ 12 апреля 2020

Вы можете взять объект для группировки и сохранить номер постфикса для каждой новой пары дата / задачи.

В результате получите значения / полезную нагрузку от объектов.

var data = [{id: 222, date: 'apr 1', todo: 'nothing' }, { id: 222, date: 'apr 2', todo: '' }, { id: 222, date: 'apr 3', todo: 'swim' }, { id: 222, date: 'apr 4', todo: 'run' }, { id: 222, date: 'apr 1', todo : '' }, { id: 222, date: 'apr 2', todo : 'jump' }, { id: 222, date: 'apr 3', todo : '' }, { id: 222, date: 'apr 4', todo : '' }],
    result = Object
        .values(data.reduce((r, { id, date, todo }) => {
            if (!r[id]) r[id] = { index: 0, key: {}, payload: { id } };
            if (!r[id].key[date]) {                    
                r[id].index++;
                r[id].key[date] = `todo${r[id].index}`;
                r[id].payload[`date${r[id].index}`] = date;
            }
            if (todo) r[id].payload[r[id].key[date]] = todo;
            return r;
        }, {}))
        .map(({ payload }) => payload);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
...