`JSON.stringify` omits custom keys in array

2.9k Views Asked by At

I am storing my array as a mixture of array an array and an object. For example assume this one:

let arrObj = [];
arrObj["x"] = 12;
arrObj.push(12);
arrObj["y"] = 15;
arrObj.push(15);

// result: arrObj = [12, 15, x: 12, y: 15]

so that, I can access the value 12 even using arrObj[0] and arrObj["x"]. And this way, I can do a repeat for on it.

But when I stringify it, the keys x and y get lost:

JSON.stringify(arrObj)
// result: "[12,15]"

How should I maintain those keys and their values?

3

There are 3 best solutions below

6
Pranav C Balan On BEST ANSWER

While stringifying convert it to an object using spread syntax and later parse and use Array#reduce method to generate the array.

The array keeps the property since Array is also an object in Javascript.

let arrObj = [];
arrObj["x"] = 12;
arrObj.push(12);
arrObj["y"] = 15;
arrObj.push(15);

let json = JSON.stringify({ ...arrObj });

console.log(json);

let parsed = Object.entries(JSON.parse(json)).reduce((arr, [key, value]) => (arr[key] = value, arr), []);

console.log(parsed);

FYI : But it always better to use an Object or Map for key-value pair data, not better that's the right way in my opinion.


UPDATE 1: Or you can use a main object which keeps all additional property and within it create a property which keeps the array as well.

let arrObj = {
  arr: []
};
arrObj["x"] = 12;
arrObj.arr.push(12);
arrObj["y"] = 15;
arrObj.arr.push(15);

let json = JSON.stringify(arrObj);

console.log(json);

let parsed = JSON.parse(json);

console.log(parsed);


UPDATE 2: The second approach cause issue if you are trying to set property named arr(in my case) so keep object values in separate property.

let arrObj = {
  arr: [],
  obj: {}
};
arrObj.obj["x"] = 12;
arrObj.arr.push(12);
arrObj.obj["y"] = 15;
arrObj.arr.push(15);

let json = JSON.stringify(arrObj);

console.log(json);

let parsed = JSON.parse(json);

console.log(parsed);

10
CertainPerformance On

Arrays should contain numeric-indexed values only. If you want keys in addition to values, use an object:

const obj = {};
obj.x = 12;
obj[0] = 12;
obj.y = 15;
obj[1] = 15;

console.log(JSON.stringify(obj));

for (let i = 0; i in obj; i++) {
  console.log(obj[i]);
}

You could also consider using an object that contains both an array and your custom key-value pairs, eg:

const arr = [];
const obj = { arr };
obj.x = 12;
obj.y = 15;
arr.push(12);
arr.push(15);

console.log(JSON.stringify(obj));

1
Tyro Hunter On

Here is a fancy 1 liner solution:

let arrObj = [];
    arrObj["x"] = 12;
    arrObj.push(12);
    arrObj["y"] = 15;
    arrObj.push(15);

var string = JSON.stringify(Object.keys(arrObj).reduce((acc, cur) => ((acc[cur] = arrObj[cur]), acc), {}));

console.log(string);

P.S: I thought it's worthy to mention that you might encounter an unexpected behaviour because in JS, there is no guarantee that object properties are ordered (as you wanted to). Does JavaScript Guarantee Object Property Order?