Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert into array at every nth position

What I'm trying to achieve is to create a formatted number with thousands-delimiter from a simple string input. So my input would look something like let input = "12345" and my expected return value should look like "12,345".

I know there are already several libraries, which take care of this, but I want to keep it simple and just do it by myself. My current solution is a bit redundant (because of the double .reverse()) and I'm pretty sure, that there is a better solution.

let array = input.split('');

array.reverse();

for (let i = 3; i < array.length; i += 4) {
    array.splice(i, 0, ',');
}

array.reverse();

return array.join('');
like image 770
mecograph Avatar asked Sep 08 '25 09:09

mecograph


2 Answers

I have made a similar answer for another question: Insert new element after each nt-h array elements. It is a generalized method that insert a token every N positions. The solution uses a while loop with the Array.splice() method. To meet your request, I have extended it to support start the inserts from the end of the array. Just another option...

let insertTokenEveryN = (arr, token, n, fromEnd) => {

    // Clone the received array, so we don't mutate the
    // original one. You can ignore this if you don't mind.

    let a = arr.slice(0);
    
    // Insert the <token> every <n> elements.

    let idx = fromEnd ? a.length - n : n;

    while ((fromEnd ? idx >= 1 : idx <= a.length))
    {
        a.splice(idx, 0, token);
        idx = (fromEnd  ? idx - n : idx + n + 1);
    }

    return a;
};

let array = Array.from("1234567890");
let res1 = insertTokenEveryN(array, ",", 3, true);
console.log(res1.join(""));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

But, obviously, like people commented, your best option for this will be using input.toLocaleString('en-US'):

let input = "1234567890";
console.log(Number(input).toLocaleString("en-US"));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
like image 200
Shidersz Avatar answered Sep 10 '25 05:09

Shidersz


Although in your example the you finish with a string, the title says "into array". This is quite a compact way using lodash:

import { chunk, flatten } from 'lodash'

const ADD_EVERY = 5
const ITEM_TO_ADD = {}

const data = flatten(
  chunk(input, ADD_EVERY).map((section) => 
  section.length === ADD_EVERY ? [...section, ITEM_TO_ADD] : section
)

It is conceptually kind of similar to doing a split().join()

like image 45
James Trickey Avatar answered Sep 10 '25 04:09

James Trickey