Как посчитать кол-во повторяющихся элементов в массиве. На выходе новый массив с сохранением последовательности

Нужно посчитать стоимость проживания за девять ночей. Цены по периодам могут меняться. Что-то вроде 4 ночи по 9700, 2 ночи по 7600, 3 ночи по 10000. Сделал так:

const prices = [9700, 9700, 9700, 9700, 7600, 7600, 10000, 10000, 10000];

const countedPrices = [];
let price = 0;
let index = 0;
let count = 1;

for (let i = 0; i < prices.length; i++) {
  if (i === 0) {
    price = prices[i];
  }
  if (prices[i] === price) {
    countedPrices[index] = [prices[i], count];
    count ++;
  } else {
    price = prices[i];
    index++;
    count = 1;
    countedPrices[index] = [prices[i], count];
    count++;
  }
}

console.log(countedPrices); // [[9700, 4], [7600, 2], [10000, 3]]

В интернете нашел такой пример:

const countedPrices = prices.reduce((allPrices, price) => {
  const currCount = allPrices[price] ?? 0;
  return {
    ...allPrices, 
    [price]: currCount + 1,
  }
}, {});

console.log(countedPrices); // { 7600: 2, 9700: 4, 10000: 2 }

Но как видно из результата, ключи сортируются по возрастанию и не понятно какой период был первым, какой вторым и т.д. В итоге сделал сам как в первом примере.

Подскажите, пожалуйста, может есть более изящный способ это сделать?


Ответы (2 шт):

Автор решения: Andrey Semykin

Так достаточно изящно? :)))

const prices = [9700, 9700, 9700, 9700, 7600, 7600, 10000, 10000, 10000];

const countedPricesMap = new Map();

prices.forEach(function(price) {
      let p = countedPricesMap.get(price);
      if (p == undefined) countedPricesMap.set(price, 1);
      else countedPricesMap.set(price, p + 1);
    });

    console.log(Array.from(countedPricesMap)); // [[9700, 4], [7600, 2], [10000, 3]]

→ Ссылка
Автор решения: Pavel Nazarian

const prices = [9700, 9700, 9700, 9700, 7600, 7600, 10000, 10000, 10000];

let result = [...new Set(prices)]
             .map(i => [i,prices.filter(e=>e===i).length])

console.log(result)

→ Ссылка