Сопоставьте массив и проверьте наличие определенного ключа, если он имеет одинаковое значение, затем объедините два

avatar
konstantforce
8 августа 2021 в 21:42
69
4
3

Вот чего я пытаюсь достичь:

У меня есть этот массив:

const data = [
  { paidOn: "01", workstreamName: "Leeann",   amount: 242759 },
  { paidOn: "02", workstreamName: "Angelico", amount: 58142  },
  { paidOn: "03", workstreamName: "Zorine",   amount: 419310 },
  { paidOn: "02", workstreamName: "Janine",   amount: 135015 },
  { paidOn: "04", workstreamName: "Shannon",  amount: 6396   },
  { paidOn: "01", workstreamName: "Wang",     amount: 198277 },
];
  1. Мне нужно найти все ключи "paidOn" с одинаковым значением и объединить их.
  2. Используйте значение workstreamName в качестве ключа и значение суммы в качестве значения для нового ключа.

Вывод будет выглядеть следующим образом:

const data = [
  { paidOn:"01", "Leeann":  242759, "Wang":   198277 },
  { paidOn:"02", "Angelico": 58142, "Janine": 135015 },
  { paidOn:"03", "Zorine":  419310  },
  { paidOn:"04", "Shannon":  6396   }
  ];

До сих пор мне удалось выполнить шаг 2 с помощью следующего кода, но я не могу понять, как выполнить шаг 1:

const data = [
  { paidOn: "01", workstreamName: "Leeann", amount: 242759 },
  { paidOn: "02", workstreamName: "Angelico", amount: 58142 },
  { paidOn: "03", workstreamName: "Zorine", amount: 419310 },
  { paidOn: "04", workstreamName: "Janine", amount: 135015 },
  { paidOn: "05", workstreamName: "Shannon", amount: 6396 },
  { paidOn: "05", workstreamName: "Wang", amount: 198277 },
  { paidOn: "06", workstreamName: "Maurise", amount: 389081 },
  { paidOn: "07", workstreamName: "Nike", amount: 125030 },
  { paidOn: "08", workstreamName: "Teodor", amount: 142803 },
  { paidOn: "08", workstreamName: "Stefan", amount: 398831 },
  { paidOn: "09", workstreamName: "Fancy", amount: 353254 },
  { paidOn: "10", workstreamName: "Salli", amount: 492496 },
  { paidOn: "10", workstreamName: "Daniela", amount: 147206 },
  { paidOn: "11", workstreamName: "Tandy", amount: 362225 },
  { paidOn: "11", workstreamName: "Sidnee", amount: 381233 },
  { paidOn: "11", workstreamName: "Kordula", amount: 86582 },
  { paidOn: "12", workstreamName: "Dedra", amount: 443826 },
  { paidOn: "02", workstreamName: "Essy", amount: 449565 },
];

const workstreamNames = data.map((item) => {
  return item.workstreamName
});

const amount = data.map((item) => {
  return item.amount
});

const res = Object.fromEntries(workstreamNames.map((_, i) => [workstreamNames[i], amount[i]]))

console.log(res);

Буду признателен за любую помощь или подсказку.

Источник
Mister Jojo
8 августа 2021 в 22:03
0

непонятно, workstreamName уникальны для одного и того же paidOn, или их надо складывать вместе?

Ответы (4)

avatar
Guerric P
8 августа 2021 в 21:53
3

Вы можете использовать Array.prototype.reduce() следующим образом:

const data = [
  { paidOn: "01", workstreamName: "Leeann", amount: 242759 },
  { paidOn: "02", workstreamName: "Angelico", amount: 58142 },
  { paidOn: "03", workstreamName: "Zorine", amount: 419310 },
  { paidOn: "02", workstreamName: "Janine", amount: 135015 },
  { paidOn: "04", workstreamName: "Shannon", amount: 6396 },
  { paidOn: "01", workstreamName: "Wang", amount: 198277 },
];

const result = data.reduce((acc, { paidOn, workstreamName, amount }) => {
    const found = acc.find(x => x.paidOn === paidOn);
    found ? found[workstreamName] = amount : acc.push({ paidOn, [workstreamName]: amount});
    return acc;
}, []);

console.log(result);
avatar
Farhad Rad
8 августа 2021 в 22:19
2

Это может быть полезно

const data = [
  { paidOn: "01", workstreamName: "Leeann", amount: 242759 },
  { paidOn: "02", workstreamName: "Angelico", amount: 58142 },
  { paidOn: "03", workstreamName: "Zorine", amount: 419310 },
  { paidOn: "04", workstreamName: "Janine", amount: 135015 },
  { paidOn: "05", workstreamName: "Shannon", amount: 6396 },
  { paidOn: "05", workstreamName: "Wang", amount: 198277 },
  { paidOn: "06", workstreamName: "Maurise", amount: 389081 },
  { paidOn: "07", workstreamName: "Nike", amount: 125030 },
  { paidOn: "08", workstreamName: "Teodor", amount: 142803 },
  { paidOn: "08", workstreamName: "Stefan", amount: 398831 },
  { paidOn: "09", workstreamName: "Fancy", amount: 353254 },
  { paidOn: "10", workstreamName: "Salli", amount: 492496 },
  { paidOn: "10", workstreamName: "Daniela", amount: 147206 },
  { paidOn: "11", workstreamName: "Tandy", amount: 362225 },
  { paidOn: "11", workstreamName: "Sidnee", amount: 381233 },
  { paidOn: "11", workstreamName: "Kordula", amount: 86582 },
  { paidOn: "12", workstreamName: "Dedra", amount: 443826 },
  { paidOn: "02", workstreamName: "Essy", amount: 449565 },
];

var result = data
      .map(x => ({"paidOn": x.paidOn, [x.workstreamName]: x.amount}))
      .reduce((t, x) => ({...t, [x.paidOn]: {...t[x.paidOn], ...x}}), {});
avatar
enzo
8 августа 2021 в 21:55
4

Вот как вы можете это сделать - это изменяет этот ответ, чтобы вернуть пользовательский словарь:

const data = [
  { paidOn: "01", workstreamName: "Leeann", amount: 242759 },
  { paidOn: "02", workstreamName: "Angelico", amount: 58142 },
  { paidOn: "03", workstreamName: "Zorine", amount: 419310 },
  { paidOn: "02", workstreamName: "Janine", amount: 135015 },
  { paidOn: "04", workstreamName: "Shannon", amount: 6396 },
  { paidOn: "01", workstreamName: "Wang", amount: 198277 },
];

const key = "paidOn";

const result = Object.values(data.reduce(function(acc, x) {
    const sub = (acc[x[key]] = acc[x[key]] || {"paidOn": x[key]});
    sub[x["workstreamName"]] = x["amount"];
    return acc;
  }, {}));

console.log(result);

Примечание: Это O(n) подход.

avatar
Kelvin Schoofs
8 августа 2021 в 21:45
2

Вы можете сделать что-то вроде этого:

const data = [
    { paidOn: "01", workstreamName: "Leeann", amount: 242759 },
    { paidOn: "02", workstreamName: "Angelico", amount: 58142 },
    { paidOn: "03", workstreamName: "Zorine", amount: 419310 },
    { paidOn: "02", workstreamName: "Janine", amount: 135015 },
    { paidOn: "04", workstreamName: "Shannon", amount: 6396 },
    { paidOn: "01", workstreamName: "Wang", amount: 198277 },
    { paidOn: "01", workstreamName: "Wang", amount: 123 },
];

const result = {};
for (const { paidOn, workstreamName, amount } of data) {
    let row = result[paidOn];
    if (!row) row = result[paidOn] = {};
    row[workstreamName] = (row[workstreamName] || 0) + amount;
}
console.log(result);

Два примечания:

  • Вместо { paidOn: '', name1: 123, name2: 456 } я использовал объект типа { [paidOn]: { name1: 123, name2: 456 } }, чтобы его было легче использовать позже. Это также предотвращает ошибку, когда workstreamName по какой-то причине равно paidOn.
  • Mine берет сумму одноименных значений same-paidOn, например. Wang в 01.
konstantforce
8 августа 2021 в 22:11
0

Спасибо @Kelvin Schoofs за вашу помощь!