I've created a function that exponentiates common factors.
I'd like to optimize/simplify it because, as you can see, it's very messy and not very performant
function App() {
return (
<View results={ [2, 2, 3, 8, 8, 8, 100] } //only an example
)
}
function View({ results }) {
const defaultView = results.reduce((previous, current) => previous.includes(current) ? ((previous[previous.length - 1] = [current, 2]), previous) : previous.some(element => current === element[0]) ? (previous[previous.length - 1][1]++, previous) : [...previous, current], []).map((element, index) =>
<li key={`${index} : ${element}`}>
{
Array.isArray(element) ? <>{element[0]}<sup>{element[1]}</sup></> : element
}
</li>
)
}
thanks
1 Answer 1
You can avoid the edge cases by uniformly using the format [data, count]
, rather than special casing the count-of-1 case. Your reduction will then look like this:
arr = [2, 2, 3, 8, 8, 8, 100]
arr.reduce(
(m, x) => {
const prev = m[m.length-1]
return x == prev[0] ? (prev[1]++, m) : (m.push([x, 1]), m)
},
[[]]
).slice(1)
// [ [ 2, 2 ], [ 3, 1 ], [ 8, 3 ], [ 100, 1 ] ]
Now in your view you can branch on "is the count > 1" rather than on "is it an array".
Arguably, the ternary with side-effects inside using the comma operator is too clever, but it seemed like you were going for terseness. It easy enough to expand that out into a traditional if
statement though. Also, you can reformat it into a 1-liner, but I prefer the clearer formatting at the expense of more lines.