'Javascript: Replace same consecutive elements of an array into one item that shows their count in
I have an array like this :
const array = [1, 3, x, x, 4, x, x, x, 9, x, x, x, x, 7]
I want to turn all consecutive elements which has the value of x into one element that shows their count between numbers such as :
const newArray = [1, 3, '2x', 4, '3x', 9, '4x', 7]
For instance, 3 consecutive x in the array like [x, x, x] should be turned into one ['3x'] while numbers should stay untouched.
Solution 1:[1]
Maybe there's a better solution for achieving that. Of course, there's! But here is a solution by using the for loop. Check every iteration if the element is x, increase the x value by 1. And if the current element is not x, then reset the x variable to 0.
Sample Result:
const array = [1, 3, 'x', 'x', 4, 'x', 'x', 'x', 9, 'x', 'x', 'x', 'x', 7];
let x = 0;
let result = [];
for (let i = 0; i < array.length; i++) {
if (array[i] === 'x') {
x++;
if (array[i + 1] === 'x') continue;
result.push(`${x}x`);
continue;
}
x = 0;
result.push(array[i]);
}
console.log(result);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration
Solution 2:[2]
const array = [1, 3, 'x', 'x', 4, 'x', 'x', 'x', 9, 'x', 'x', 'x', 'x', 7]
const newArray = array.map(item => `${item}`).reduce((acc, curr)=>{
if(curr !== 'x') return [...acc, curr];
const previous = acc.pop();
if(!previous || !previous.includes('x')) return [...acc, previous, '1x'];
const xCounter = 1 + parseInt(previous.match(/\d+/)[0]);
return [...acc, `${xCounter}x`];
},[])
console.log(newArray)
Solution 3:[3]
The simplest way is just to iterate all elements:
// Your array
const array = [
1,
3,
"x",
"x",
4,
"x",
"x",
"x",
9,
"x",
"x",
"x",
"x",
7
];
// Create new array
const newArr = [];
// Set internal value repeat counter
let cn = 1;
// Iterate array
for(let i = 0; i < array.length; i++) {
// Set trigger
let trig = 1;
// If next param exist and it is equals current
if(array[i+1] && array[i+1] === array[i]) {
// Increase counter
cn++;
// Set trigger to false
trig = 0;
}
// If trigger is true
if(trig) {
// If internal counter greater then 1
// push previous value and its counter
if(cn > 1) {
newArr.push(`${cn}${array[i-1]}`);
// Reset counter
cn = 1;
}
// Else just push current value
else newArr.push(array[i]);
}
}
// Test
console.log(newArr);
And then you can try to shrink the code with something more advanced:
// Your array
const arr = [1,3,"x","x",4,"x","x","x",9,"x","x","x","x",7];
// Use flatMap
let cn = 1;
const res = arr.flatMap((e, i, a) => {
return a[i+1] && a[i+1] == e ? (cn++) && [] :
cn > 1 ? (()=>{const t = cn; cn = 1; return t+''+a[i-1]})() : e;
});
// Result
console.log(res);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | EEAH |
| Solution 3 |
