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

Original = [
    {id: 1, value: 12.2494, time: "00:00:00.14"},
    {id: 1, value: 4.5141, time: "00:00:01.138"},
    {id: 1, value: 2.85930, time: "00:00:02.138"},
    {id: 1, value: 1.0364, time: "00:00:03.146"},
    {id: 2, value: 4.3510, time: "00:09:15.157"},
    {id: 2, value: 3.90, time: "00:09:16.115"},
    {id: 2, value: 3.544, time: "00:09:17.116"},
    {id: 2, value: 3.247, time: "00:09:18.157"}
]

Ожидаемый результат

data[1]={value:[12.494, 4.5141...],time: ["00:00:00.14","00:00:01.138"]...} 
data[2]={value:[4.3510, 3.90...],time: ["00:09:15.157","00:09:16.115"]...}

Я пробовал что-то подобное, но возвращает только одно значение

var data= {};
original.forEach(function(item) {
    var id = item.id;
    data[id] = {
        value:[],
        time:[]
    }
    data[id].value.push(item['value']);
    data[id].time.push(item['time']);
})
0
Fiona 13 Мар 2018 в 05:03

2 ответа

Лучший ответ

Вы можете использовать функцию reduce из массивов.

Проверить текущий id в аккумуляторе;

Если он существует, нажмите на уже сохраненные values и times

Или создайте template object и нажмите values и times

var Original=[{id: 1, value: 12.2494,  time: "00:00:00.14"},{id: 1, value: 4.5141, time: "00:00:01.138"},{id: 1, value: 2.85930,  time: "00:00:02.138"},{id: 1, value: 1.0364,  time: "00:00:03.146"},{id: 2, value: 4.3510,  time: "00:09:15.157"},{id: 2, value: 3.90, time: "00:09:16.115"},{id: 2, value: 3.544, time: "00:09:17.116"},{id: 2, value: 3.247,  time: "00:09:18.157"}];

var data = Original.reduce((a, c) => {
  var current = (a[c.id] || (a[c.id] = {value: [], time: []}));
  current.value.push(c.value);
  current.time.push(c.time);
  
  return a;
}, {});

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2
Ele 13 Мар 2018 в 02:48

Оригинальный ответ отлично работает, но если у вас есть иррациональное отвращение к использованию push (если объект создается и изменяется только при закрытии, действительно ли он меняется?):

const original = [
    {id: 1, value: 12.2494, time: "00:00:00.14"},
    {id: 1, value: 4.5141, time: "00:00:01.138"},
    {id: 1, value: 2.85930, time: "00:00:02.138"},
    {id: 1, value: 1.0364, time: "00:00:03.146"},
    {id: 2, value: 4.3510, time: "00:09:15.157"},
    {id: 2, value: 3.90, time: "00:09:16.115"},
    {id: 2, value: 3.544, time: "00:09:17.116"},
    {id: 2, value: 3.247, time: "00:09:18.157"}
]

const data = original.reduce((x, y) => x[y.id]
    ? Object.assign({}, x, {
        [y.id]: {
            value: x[y.id]
                .value
                .concat(y.value),
            time: x[y.id]
                .time
                .concat(y.time)
        }
    })
    : Object.assign({}, x, {
        [y.id]: {
            value: [y.value],
            time: [y.time]
        }
    }), {})

Или, если в данных есть дыры, и вы не хотите добавлять undefined, уменьшите до уникальных идентификаторов, сопоставьте этот список, отфильтруйте исходный список, уменьшите до слияния:

    const unoriginal = [
    {id: 1, value: 12.2494, time: "00:00:00.14"},
    {id: 1, value: 4.5141, time: "00:00:01.138"},
    {id: 1, value: 2.85930, time: "00:00:02.138"},
    {id: 1, value: 1.0364},
    {id: 2, time: "00:09:15.157"},
    {id: 2, value: 3.90, time: "00:09:16.115"},
    {id: 2, value: 3.544, time: "00:09:17.116"},
    {id: 2, value: 3.247, time: "00:09:18.157"}
]

const otherData = unoriginal.reduce((x, y) => x.includes(y.id)
    ? x
    : x.concat(y.id), []).map(x => Object.assign({}, {
    [x]: {
        value: unoriginal
            .filter(y => x === y.id)
            .reduce((z, a) => a.value
                ? z.concat(a.value)
                : z, []),
        time: unoriginal
            .filter(y => x === y.id)
            .reduce((b, c) => c.time
                ? b.concat(c.time)
                : b, [])
    }
})).reduce((x, y) => Object.assign.apply(null, [x].concat(y)))
0
Austin Coose 13 Мар 2018 в 17:55