Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting object properties which are array like to array is not working

I have an nested object like following(it can have any depth):

{
    "a": 5,
    "b": {
        "0": 1,
        "1": "x"
    },
    "x": {
        "a": 1,
        "1": "z"
    },
    "c": {
        "0": 3,
        "1": "Am",
        "3":{
            "0": 3,
            "1": "x",
            "2":{
                "0": 3,
                "1": "Y"
            },
            "length": 3
        },
        "length": 4
    }
}

I have to convert it as following(object may or may not have length property):

{
    "a": 5,
    "x": {
        "a": 1,
        "1": "z"
    },
    "b": [1,"x"],
    "c": [3, "Am",undefind, [ 3, "x", [ 3, "Y" ] ] ]
}

I written method like following:

function formatObjToArr(obj) {
    var kys = Object.keys(obj);
    var isObj = (/[^0-9]/g).test(kys.join('')) && !Array.isArray(obj);
    if(!isObj){
        obj.length===undefined && (obj.length = Math.max.apply(null,kys.map(function (i) { return parseInt(i) }))+1);
        obj = Array.prototype.map.apply(obj,[function (i) { return i}]);
        obj.forEach(function (i) {
            (typeof i === "object" && i!==null) && formetObjToArr(i);
        })
    }else {
        for (var property in obj) {
            if (obj.hasOwnProperty(property) && property!=='length') {
                if (typeof obj[property] === "object" && obj[property]!==null) {
                    formetObjToArr(obj[property]);
                }
            }
        }
    }
}

But it just adds the length property it is not changing the type. output of my code is as follows:

{
  "a": 5,
  "b": {
      "0": 1,
      "1": "x",
      "length": 2
   },
  "x": {
      "a": 1,
      "1": "z"
  },
  "c": {
      "0": 3,
      "1": "Am",
      "3": {
          "0": 3,
          "1": "x",
          "2": {
              "0": 3,
              "1": "Y",
              "length": 2
          },
          "length": 3
      },
      "length": 4
  }
}
like image 427
Akhilesh Kumar Avatar asked Apr 24 '26 00:04

Akhilesh Kumar


2 Answers

You could take a check for object and check if the keys are in the wanted range for an index or length, then create an array of it. This array should be converted, too.

function convert(object) {
    var keys;
    if (!object || typeof object !== 'object') {
        return object;
    }

    keys = Object.keys(object);        
    if (keys.every(k => k === 'length' || Math.floor(k) === +k && k >= 0 && k < Math.pow(2, 31))) {
        return Object.assign([], object).map(convert);
    }

    return Object.assign(...keys.map(k => ({ [k]: convert(object[k]) })));
}

var data = { a: 5, b: { 0: 1, 1: "x" }, x: { 1: "z", a: 1 }, c: { 0: 3, 1: "Am", "3": { 0: 3, 1: "x", 2: { 0: 3, 1: "Y" }, length: 3 }, length: 4 } };

console.log(convert(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 122
Nina Scholz Avatar answered Apr 25 '26 14:04

Nina Scholz


var data = {
    "a": 5,
    "b": {
        "0": 1,
        "1": "x"
    },
    "c": {
        "0": 3,
        "1": "Am",
        "length": 2
    }
}


for(const d in data){
    if(typeof data[d] === 'object'){
        delete data[d]['length'];
        data[d] = Object.values(data[d]);
    }
}

console.log(data);
like image 42
Chayan Avatar answered Apr 25 '26 12:04

Chayan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!