Использование уменьшения внутренней карты

#javascript #reduce

#javascript #уменьшить

Вопрос:

Всякий раз, когда я хотел бы использовать reduce внутри функции map, я получаю сообщение об ошибке «reduce — это не функция».

У меня есть массив, в котором я сопоставляю 2 ключа. Дата и сумма. Ниже приведен массив с объектами.

 const dividendArrayFiltered = [
    {
        "date": "2021-11-09",
        "amount": 0.5
    },
    {
        "date": "2021-11-08",
        "amount": 0.5
    },
    {
        "date": "2021-11-08",
        "amount": 0.5
    },
    {
        "date": "2021-11-11",
        "amount": 1
    },
    {
        "date": "2021-11-11",
        "amount": 1
    }
]
 

В этой карте я хотел бы уменьшить значения с той же датой.

Это код, который выдает ошибку. Не совсем уверен, почему функция уменьшения не работает. Надеюсь, вы могли бы мне помочь. Спасибо!

 const summedDividend = dividendArrayFiltered.map(({ date, amount }) => {
    const grouped = date.reduce(
      (a, d, i) => a.set(d, (a.get(d) ?? 0)   amount[i]),
      new Map()
    );

    return {
      date: [...grouped.keys()],
      amount: [...grouped.values()],
    };
  });
 

Комментарии:

1. Вы вообще этого не хотите map , вы просто хотите напрямую обращаться к reduce исходному массиву.

2. Вы не можете сопоставить объект, вы можете, если преобразуете его в Object.entries

Ответ №1:

Ваше собственное решение не работает, потому что внутри функции map у вас есть доступ только к текущему элементу, а не к массиву, но функция reduce может использоваться только для массивов.

Альтернативное решение:

Вы можете создать пустой массив, в который вы помещаете только эти элементы из вашего исходного массива, которые не имеют той же даты, что и один из элементов в вашем новом массиве.

   let uniqueArray = [] 

  // iterate through all array elements
  dividendArrayFiltered.forEach((item) => {
    // check if an element with the current item date exists in your new uniqueArray and which position index it has
    const itemPos = uniqueArray.findIndex(uniqueItem => uniqueItem.date == item.date)
    // if the index is negative, it's not included in the array, so you push your item to the new array
    if(itemPos < 0) {
      uniqueArray.push(item)
    }
    // if it's included, you take the old amount and add your new value
    else {
      uniqueArray[itemPos].amount = uniqueArray[itemPos].amount   item.amount;
    }
  });

  console.log(uniqueArray);
 

В uniqueArray теперь только уникальные элементы даты.

Комментарии:

1. Спасибо, что помогли мне, ценю это! Однако это удаляет дубликат. Я бы хотел объединить дубликат. Таким образом, «дата»: «2021-11-11», будет иметь значение 2 вместо 1.

2. Я не видел, что вы хотите суммировать суммы, я отредактировал свой ответ, поэтому теперь он должен работать так, как вы хотите.

Ответ №2:

Вы можете уменьшить исходный массив напрямую, а также использовать findIndex() :

 const dividendArrayFiltered = [
  { date: '2021-11-09', amount: 0.5 },
  { date: '2021-11-08', amount: 0.5 },
  { date: '2021-11-08', amount: 0.5 },
  { date: '2021-11-11', amount: 1 },
  { date: '2021-11-11', amount: 1 }
]

const grouped = dividendArrayFiltered.reduce((a, c) => {
  const dateIndex = a.findIndex(o => o.date === c.date)
  if (dateIndex !== -1) a[dateIndex].amount  = c.amount
  else a.push({ date: c.date, amount: c.amount })

  return a
}, [])

console.log(grouped) 
 .as-console-wrapper { min-height: 100% } 

Комментарии:

1. Потрясающе @aerial301, именно то, что мне было нужно!