Search code examples
arraysnode.jsjsonconcatenation

How to change format array in node js from 1 string become another object


I have a json like this :

{
    "status": 1,
    "message": "ok",
    "data": [
        {
            "tenor": "23"
        },
        {
            "tenor": "17"
        },
        {
            "tenor": "37"
        },
        {
            "tenor": "27,29"
        },
        {
            "tenor": "33,35"
        }
    ]
}

and I want the result to be something like this:

{ "status": 1, "message": "ok", "data": [ { "tenor": "23" }, { "tenor": "17" }, { "tenor": "37" }, { "tenor": "27" }, { "tenor": "29" }, { "tenor": "33" }, { "tenor": "35" } ] }

What I have tried:

var arrayCoba = [];
var array1 = { "status": 1, "message": "ok", "data": [ { "tenor": "23" }, { "tenor": "17" }, { "tenor": "37" }, { "tenor": "27,29" }, { "tenor": "33,35" } ] }

for(var i = 0; i<array1.data.length; i++){
    var string = array1.data[i].tenor;
    var substring = ",";

    if(string.includes(substring) == true){
        var tenor = array.data[i].tenor;
        var tenorArr = tenor.split(',');
        var dataTenor = tenorArr.map(tenor => ({ tenor }));
        arrayCoba.push(dataTenor);
    }
 }

 var dataHasil = array1.data.concat(arrayCoba);

 return res.json({status:1,message:'ok',data:dataHasil}); 

but the result that i get is :

{
    "status": 1,
    "message": "ok",
    "data": [
        {
            "tenor": "23"
        },
        {
            "tenor": "17"
        },
        {
            "tenor": "37"
        },
        {
            "tenor": "27,29"
        },
        {
            "tenor": "33,35"
        },
        [
            {
                "tenor": "27"
            },
            {
                "tenor": "29"
            }
        ],
        [
            {
                "tenor": "33"
            },
            {
                "tenor": "35"
            }
        ]
    ]
}

can anyone help me? Thank you ..


Solution

  • var dataTenor = tenorArr.map(tenor => ({ tenor })); return an array of tenor object. arrayCoba.push(dataTenor); add the array in other array and is for this you get an array in array.

    use spread operator -> arrayCoba.push(...dataTenor);

    for (var i = 0; i < array1.data.length; i++) {
        var string = array1.data[i].tenor;
        var substring = ",";
    
        if (string.includes(substring) == true) {
            var tenor = array1.data[i].tenor;
            var tenorArr = tenor.split(',');
            var dataTenor = tenorArr.map(tenor => ({
                tenor
            }));
            arrayCoba.push(...dataTenor);
        } else {
            arrayCoba.push(array1.data[i]);
        }
    }
    
    var dataHasil = arrayCoba;
    

    UPDATE: a another way with map operator.

    var substring = ',';
    
    var copyDataTenors = array1.data;
    var arrayCoba = "".concat(copyDataTenors
        .map(obj => obj.tenor))
        .split(substring)
        .map(tenorString => ({
            'tenor': tenorString
        }))
    
    var dataHasil = arrayCoba;
    

    UPDATE: With recursion and more generic than previous solutions

    const data = [{
            "tenor": "23"
        },
        {
            "tenor": "17"
        },
        {
            "tenor": "37"
        },
        {
            "tenor": "27,29"
        },
        {
            "tenor": "33,35"
        }
    ]
    
    /**
     *
     * @param {*} fn function callback
     * @param {*} v string[] or string
     * @param {*} attr string
     * @param {*} substring string
     */
    const processDeepObject = (fn, v, attr, substring) => {
        return typeof v === 'string' ? {
            [attr]: v
        } : v[attr] ? fn(v[attr].split(substring), attr, substring) : [];
    }
    
    /**
     * Version 1
     * @param {*} arr Array of objects
     * @param {*} attr target you want keep (for this use case tenor)
     * @param {*} substring which char to split the data (for this use case ',')
     */
    const deepObjectFlatten = (arr, attr, substring) => [].concat(...arr.map((v) => processDeepObject(deepObjectFlatten, v, attr, substring)));
    
    
    
    /**
     * Version 2 same as version 1 but compact
     * @param {*} arr Array of objects
     * @param {*} attr target you want keep (for this use case tenor)
     * @param {*} substring which char to split the data (for this use case ',')
     */
    const deepObjectFlattenV2 = (arr, attr, substring) => [].concat(...arr.map((v) => {
        return typeof v === 'string' ? {
            [attr]: v
        } : v[attr] ? deepObjectFlattenV2(v[attr].split(substring), attr, substring) : [];
    }));
    
    
    console.log(deepObjectFlatten(data, 'tenor', ','))
    console.log(deepObjectFlattenV2(data, 'tenor', ','))
    /*
    Output :
    //v1
    [ { tenor: '23' },
      { tenor: '17' },
      { tenor: '37' },
      { tenor: '27' },
      { tenor: '29' },
      { tenor: '33' },
      { tenor: '35' } ]
    
    //v2
      [ { tenor: '23' },
      { tenor: '17' },
      { tenor: '37' },
      { tenor: '27' },
      { tenor: '29' },
      { tenor: '33' },
      { tenor: '35' } ]
     */