I have this matrix algorithm:
Input:
const input = [
['Camry', 'Toyota', 'Jan', 'Nowhere Town', '50'],
['Camry', 'Toyota', 'Feb', 'Nowhere Town', '70'],
['Camry', 'Toyota', 'Jan', 'Random City', '3000'],
['Prius', 'Toyota', 'Jan', 'Nowhere Town', '60'],
['Prius', 'Toyota', 'Jan', 'Random Town', '60'],
['Prius', 'Toyota', 'Mar', 'Nowhere Town', '50'],
['Civic', 'Honda', 'Jan', 'Nowhere Town', '10'],
['Civic', 'Honda', 'Feb', 'Nowhere Town', '10'],
['Civic', 'Honda', 'Mar', 'Random Town', '10'],
['Civic', 'Honda', 'Mar', 'Random Town', '20'],
]
Expected output:
const output = [
['S', 'Camry', 'Toyota', 'Jan', '3050'],
['D', 1, 'Camry', 'Nowhere Town', '50'],
['D', 2, 'Camry', 'Random City', '3000'],
['S', 'Camry1', 'Toyota', 'Feb', '70'],
['D', 1, 'Camry1', 'Nowhere Town', '70'],
['S', 'Prius', 'Toyota', 'Jan', '120'],
['D', 1, 'Prius', 'Nowhere Town', '60'],
['D', 2, 'Prius', 'Random Town', '60'],
['S', 'Prius1', 'Toyota', 'Mar', '50'],
['D', 1, 'Prius1', 'Nowhere Town', '50'],
['S', 'Civic', 'Honda', 'Jan', '10'],
['D', 1, 'Civic', 'Nowhere Town', '10'],
['S', 'Civic1', 'Honda', 'Feb', '10'],
['D', 1, 'Civic1', 'Nowhere Town', '10'],
['S', 'Civic2', 'Honda', 'Mar', '30'],
['D', 1, 'Civic2', 'Random Town', '10'],
['D', 2, 'Civic2', 'Random Town', '20'],
]
In words: If rows contain the same Brand, the same Make and the same Month add a Summary Row on top with total sales and add listed order for each details row.
Add an extra number string (1, 2, ...) behind the Make for both S
and D
rows if the Month is later than the first Month in the table.
This question is similar to my old question here but this one requires extra logic to handle the Month difference.
This is the old code I use:
const groupReport = arr => {
const result = [].concat(...arr
.reduce((m, [brand, make, month, town, amount]) => {
var key = [brand, make, month].join('|'),
data = m.get(key) || [['S', brand, make, month, '0']];
data.push(['D', data.length, brand, town, amount]);
data[0][4] = (+data[0][4] + +amount).toString();
return m.set(key, data);
}, new Map)
.values()
)
return result
}
The old code returns this result:
const oldOutput = [
['S', 'Camry', 'Toyota', 'Jan', '3050'],
['D', 1, 'Camry', 'Nowhere Town', '50'],
['D', 2, 'Camry', 'Random City', '3000'],
['S', 'Camry', 'Toyota', 'Feb', '70'],
['D', 1, 'Camry', 'Nowhere Town', '70'],
['S', 'Prius', 'Toyota', 'Jan', '120'],
['D', 1, 'Prius', 'Nowhere Town', '60'],
['D', 2, 'Prius', 'Random Town', '60'],
['S', 'Prius', 'Toyota', 'Mar', '50'],
['D', 1, 'Prius', 'Nowhere Town', '50'],
['S', 'Civic', 'Honda', 'Jan', '10'],
['D', 1, 'Civic', 'Nowhere Town', '10'],
['S', 'Civic', 'Honda', 'Feb', '10'],
['D', 1, 'Civic', 'Nowhere Town', '10'],
['S', 'Civic', 'Honda', 'Mar', '30'],
['D', 1, 'Civic', 'Random Town', '10'],
['D', 2, 'Civic', 'Random Town', '20'],
]
How can I improve the old code to handle the new logic, or is there a new approach I can take?