copy array of objects - javascript

I'm having issues creating a copy of an object array. I can't get the new reference to point to a new independent array.
function OBJ1(name, tags) {
this.myname = name;
this.mytags = tags;
this.myvalue = 0;
}
function OBJ2(arg1) {
this.arg1 = arg1;
this.myarray = [];
}
var OBJ1_array = [];
var result_array2 = null;
var result;
OBJ1_array = createarray1();
for (i = 0; i < 2; i++) {
result = createarray2();
}
function createarray1() {
var myarray = [];
myarray.push(new OBJ1("NAME", [1, 2, 3]));
myarray.push(new OBJ1("others", [1, 2, 3]));
myarray.push(new OBJ1("total", [1, 2, 3]));
return myarray;
}
function createarray2() {
var newarray = $.extend(true, [], OBJ1_array); // newarray should refer to a new array, not the same one as OBJ1_array
OBJ1_array[0].myname = "CHANGED";
console.log("categories", JSON.parse(JSON.stringify(OBJ1_array)));
console.log("newarray", JSON.parse(JSON.stringify(newarray)));
}
Output:
testscript.js:45 categories (3) [{…}, {…}, {…}]0: {myname: "CHANGED", mytags: Array(3), myvalue: 0}1: {myname: "others", mytags: Array(3), myvalue: 0}2: {myname: "total", mytags: Array(3), myvalue: 0}length: 3__proto__: Array(0)
testscript.js:46 newArray (3) [{…}, {…}, {…}]0: {myname: "CHANGED", mytags: Array(3), myvalue: 0}1: {myname: "others", mytags: Array(3), myvalue: 0}2: {myname: "total", mytags: Array(3), myvalue: 0}length: 3__proto__: Array(0)
I expected OBJ1_array[0].myname="CHANGED"; to have no effect on the newly created array newArray.
Things I've tried and didn't work:
var newArray = OBJ1_array.map(a => ({...a}));
var newarray=$.extend(true,[],OBJ1_array);
How can I solve this issue?

The $.extend documentation says the following:
Undefined properties are not copied. However, properties inherited from the object's prototype will be copied over. Properties that are an object constructed via new MyCustomObject(args), or built-in JavaScript types such as Date or RegExp, are not re-constructed and will appear as plain Objects in the resulting object or array.
This means that the array with all plain object in it will be deeply merged/copied. However objects created with the new keyword will not be reconstructed. This leaves us with the following scenario:
The array copy works just fine, however since the elements in the array are created using the new keyword they are not further merged. When altering the array itself (pushing, popping, etc.) you can see that the array is indeed a copy.
The issue here is that you access one of the elements in the array and change the object (created with the new keyword). Both arrays still point to the same object, thus when reading from the other array which hold the same object reference you will also see this change.
To resolve this issue you have to also make a copy of each object in the array. Depending on your use-case you might be able to use Object.assign or Object.create have a look at the documentation before using them blindly.
I've also created a minimal example of the problem you face to give you some better understanding of the issue.
// setup
var array1, array2, array3, array4;
function Dummy(name) { this.name = name }
// test #1 - using plain objects
array1 = [{ name: 'Foo' }];
array2 = $.extend(true, [], array1);
array1[0].name = 'Bar';
console.log(array1[0].name, array2[0].name);
// test #2 - using the `new` keyword
array3 = [new Dummy('Foo')];
array4 = $.extend(true, [], array3);
array3[0].name = 'Bar';
console.log(array3[0].name, array4[0].name);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

The problem is in your loop and OBJ1 function. first time the OBJ1_array is ok but when you come second time its valued already changed..
you can try this code
function OBJ1(name, tags) {
return {myname:name, tags:tags}
//this.myvalue = 0;
}
function OBJ2(arg1) {
this.arg1 = arg1;
this.myarray = [];
}
var OBJ1_array = [];
var result_array2 = null;
var result;
OBJ1_array = createarray1();
for (i = 0; i < 2; i++) {
let tempArr = $.extend(true, [], OBJ1_array);
result = createarray2();
OBJ1_array = tempArr;
}
function createarray1() {
let myarray = [];
myarray.push(new OBJ1("NAME", [1, 2, 3]));
myarray.push(new OBJ1("others", [1, 2, 3]));
myarray.push(new OBJ1("total", [1, 2, 3]));
return myarray;
}
function createarray2() {
let newarray =$.extend(true, [], OBJ1_array);// newarray should refer to a new array, not the same one as OBJ1_array
OBJ1_array[0].myname = "CHANGED";
console.log("categories", JSON.parse(JSON.stringify(OBJ1_array)));
console.log("newarray", JSON.parse(JSON.stringify(newarray)));
}

Updated the answer. Easiest way to achieve what you want is to use JSON.stringify with JSON.parse to create a unlinked copy of array of objects.
const OBJ1 = (name, tags) => ({
myname: name,
mytags: tags,
myvalue: 0,
})
function createarray1() {
var myarray=[];
myarray.push(OBJ1("NAME", [1,2,3]));
myarray.push(OBJ1("others", [1,2,3]));
myarray.push(OBJ1("total", [1,2,3]));
return myarray;
}
const arr = createarray1()
// here you create a copy of array
const newArr = JSON.parse(JSON.stringify(arr))
// apply changes directly to the copy
newArr[0].myname = 'Something else'
console.log(newArr)
console.log(arr)

Arrays and Objects are reference types, which means that when you make a copy by assignment, you are simply copying the reference and not the underlying array/object. In your case, when copying the array, you copy all of the object references, which will still point to the objects in your original array. You need to clone the objects too for it to work.
Use Array.map() to iterate over your array and copy each item.
Use Object.create() to make a shallow clone of each object. This function takes a prototype and property descriptors to create a new object. You can use Object.getPrototypeOf() Object.getOwnPropertyDescriptors() to pass it the prototype and property descriptors of your input object.
function OBJ1(name) {
this.myname = name;
}
const array1 = [new OBJ1("NAME")];
const array2 = array1.map(obj =>
Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
)
);
array2[0].myname = 'Jack';
console.log(array1[0].myname);
console.log(array2[0].myname);

I think you need a deep cloning of your object. please use below function
function clone(src) {
var ret=(src instanceof Array ? [] : {});
for(var key in src)
{
if(!src.hasOwnProperty(key)) { continue; }
var val=src[key];
if(val && typeof(val)=='object') { val=clone(val); }
ret[key]=val;
}
return ret;
}
function OBJ1(name, tags) {
this.myname = name;
this.mytags = tags;
this.myvalue = 0;
}
function OBJ2(arg1) {
this.arg1 = arg1;
this.myarray = [];
}
var OBJ1_array = [];
var result_array2 = null;
var result;
OBJ1_array = createarray1();
for (i = 0; i < 2; i++) {
result = createarray2();
}
function createarray1() {
var myarray = [];
myarray.push(new OBJ1("NAME", [1, 2, 3]));
myarray.push(new OBJ1("others", [1, 2, 3]));
myarray.push(new OBJ1("total", [1, 2, 3]));
return myarray;
}
function createarray2() {
var newarray = clone(OBJ1_array) ; // newarray should refer to a new array, not the same one as OBJ1_array
OBJ1_array[0].myname = "CHANGED";
console.log("categories", JSON.parse(JSON.stringify(OBJ1_array)));
console.log("newarray", JSON.parse(JSON.stringify(newarray)));
}
Much Simpler Approach
var cloneOfOBJ1_array = JSON.parse(JSON.stringify(OBJ1_array));

solved cloning of an array of objects with Object.assign
const newArray = myArray.map(a => Object.assign({}, a));
or even shorter with spread syntax
const newArray = myArray.map(a => ({...a}));

Related

Original array not getting updated when changed in referenced variable

For my work, I need to access nested object array. I do not want to access it every time with full path. So I wanted to shorten the reference by assigning the actual reference to a variable.
I tried to find out existing answers, but didn't get answer for this scenario.
What I have done:
Assigned the reference of array to a variable, modified the referenced value. But the original array is not getting modified.
Below is a demo code for what I want to achieve.
let obj = {
innerObj1: {
arr: [2,3,4,5,6]
}
}
var ref = obj.innerObj1.arr;
console.log(ref);
// output [2,3,4,5,6]
ref = ref.filter(n => n%2 == 0);
console.log(ref);
// output [2,4,6]
//Original obj
console.log(obj.innerObj1.arr)
// output [2,3,4,5,6]
This is because filter method returns a new array and you are overriding it with the new value.
As stated earlier it creates a new array, it means ref variable is not referring to old array anymore. It is referring to new array created by filter method.
You can simply use for, while or do while loop to resolve your this issue.
I hope it will help you. Please find working example here:
let obj = {
innerObj1: {
arr: [2,3,4,5,6]
}
}
var ref = obj.innerObj1.arr;
console.log(ref);
// output [2,3,4,5,6]
for(let index=0; index < ref.length; index++) {
if(ref[index] % 2 === 0) {
ref[index] = ref[index]
} else{
ref.splice(index,1);
}
}
console.log(ref);
// output [2,4,6]
//Original obj
console.log(obj.innerObj1.arr)
// output [2,3,4,5,6]
when we do
var ref = obj.innerObj1.arr;
we are having a pointer to obj.innerObj1.arr
ref is reference to array when we do ref.filter(n => n%2 == 0);
to get what we want we have to do
obj.innerObj1.arr = ref.filter(n => n%2 == 0);
Just access specific indices within ref:
let obj = {
innerObj1: {
arr: [2, 3, 4, 5, 6]
}
}
const ref = obj.innerObj1.arr;
console.log(ref);
// output [2, 3, 4, 5, 6]
for(let i = 0; i < ref.length; i++) {
ref[i] = ref[i] % 2 == 0;
}
// Original obj
console.log(obj.innerObj1.arr)
// output [true, false, true, false, true]

How display only first 2 objects (javascript)

I have an object which contains arrays. Here is an image of what it looks like in my browser:
I need to display, for example, only the first 2 arrays.
So far, I have tried this
var size = 2;
var sliced = joblist.slice(0, size);
However, this does not work and I get the following message
error:slice is not a function. it doesn't have a length
Can someone help me understand what I am doing wrong?
While the keys from the object have no order, you could take the keys, sort them and take the first two keys for a new object.
var joblist = {
'2017-08-08': [1],
'2017-08-09': [2],
'2017-08-10': [3, 4, 5],
'2017-08-11': [6]
},
size = 2,
topObjects = Object.assign(
...Object
.keys(joblist)
.sort()
.slice(0, size)
.map(k => ({ [k]: joblist[k] }))
);
console.log(topObjects);
Object does not have a .slice() method.
You can use Object.entries() to get an array of property, value pairs within the object then call .slice() on that array, chain .map() to set properties and values at a new object which can be passed to Object.assign() second parameter if an object is expected result
const o = {
a:[], b:[], c:[], d:[]
}
let res = Object.assign({}, ...Object.entries(o).slice(0, 2)
.map(([key, prop]) => ({[key]:prop})));
console.log(res)
var joblist = {
'obj': [1,2,3],
'obj2': [4,5,6],
'obj3': [7,8,9],
'obj4': [10,11,12],
};
var size = 2;
var i = 0;
for (var prop in joblist) {
if (i < size) {
console.log(joblist[prop]);
}
i++;
}
Object.keys(joblist).map(function(k) {
joblist[k] = joblist[k].slice(0, 2);
});

Javascript extend Array so it duplicates and reverses

If I have an array like [1,2,3,4], and I want to duplicate and reverse it, how do I get it to return [1,2,3,4,4,3,2,1]?
Array.prototype.duplicateAndReverse = function() {
const initial = this;
const reversed = initial.reverse();
return initial.concat(reversed);
}
What am i doing wrong here? It returns [4,3,2,1,4,3,2,1]
Try this:
Array.prototype.duplicateAndReverse = function() {
const initial = this;
const reversed = initial.slice().reverse();
return initial.concat(reversed);
}
var myArray = [1,2,3,4];
alert(myArray.duplicateAndReverse());
Your code is reversing initial as well as setting reversed to the result, so you have two identical (reversed) arrays. Instead, use .slice() to duplicate the initial array, and reverse that instead.
var arr = [1,2,3,4];
for(var len = arr.length; len; len--)
arr.push(arr[len - 1]);
console.log(arr);
I don't recommend you mess with Array.prototype but here is what you want:
Array.prototype.duplicateAndReverse = function() {
let res = this.slice(); // create another copy so the original array will stay intact
for(var len = res.length; len; len--)
res.push(res[len - 1]);
return res;
}
let arr = [1, 2, 3, 4];
console.log(arr.duplicateAndReverse());
The problem was that you tried to reverse the initial array in place.Use the following optimized solution:
Array.prototype.duplicateAndReverse = function() {
return this.concat(this.slice().reverse());
}
console.log([1,2,3,4].duplicateAndReverse());
To retain the original array and create its reversed copy use Array.prototype.slice() function combined with Array.prototype.reverse() function
This is your problem because reverse() also reverse the original array
arr
var arr = [1,2,3,4]
var dup = arr.reverse()
console.log(arr) // => [4, 3, 2, 1]
console.log(dup) // => [4, 3, 2, 1]
You need to clone the original array first
var dup = arr.slice().reverse()
And then you can concat the 2 arrays to get the result. Happy coding!
Oriental solution, hihi.
var arr = [1,2,3,4];
var newArr = [];
arr.forEach((_,i) => newArr.unshift(arr[arr.length-i-1]) && newArr.push(arr[arr.length-i-1]))
console.log(newArr);

From js object to array [duplicate]

My application creates a JavaScript object, like the following:
myObj= {1:[Array-Data], 2:[Array-Data]}
But I need this object as an array.
array[1]:[Array-Data]
array[2]:[Array-Data]
So I tried to convert this object to an array by iterating with $.each through the object and adding the element to an array:
x=[]
$.each(myObj, function(i,n) {
x.push(n);});
Is there an better way to convert an object to an array or maybe a function?
If you are looking for a functional approach:
var obj = {1: 11, 2: 22};
var arr = Object.keys(obj).map(function (key) { return obj[key]; });
Results in:
[11, 22]
The same with an ES6 arrow function:
Object.keys(obj).map(key => obj[key])
With ES7 you will be able to use Object.values instead (more information):
var arr = Object.values(obj);
Or if you are already using Underscore/Lo-Dash:
var arr = _.values(obj)
var myObj = {
1: [1, 2, 3],
2: [4, 5, 6]
};
var array = $.map(myObj, function(value, index) {
return [value];
});
console.log(array);
Output:
[[1, 2, 3], [4, 5, 6]]
Simply do
Object.values(obj);
That's all!
I think you can use for in but checking if the property is not inerithed
myObj= {1:[Array-Data], 2:[Array-Data]}
var arr =[];
for( var i in myObj ) {
if (myObj.hasOwnProperty(i)){
arr.push(myObj[i]);
}
}
EDIT - if you want you could also keep the indexes of your object, but you have to check if they are numeric (and you get undefined values for missing indexes:
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
myObj= {1:[1,2], 2:[3,4]}
var arr =[];
for( var i in myObj ) {
if (myObj.hasOwnProperty(i)){
if (isNumber(i)){
arr[i] = myObj[i];
}else{
arr.push(myObj[i]);
}
}
}
If you know the maximum index in you object you can do the following:
var myObj = {
1: ['c', 'd'],
2: ['a', 'b']
},
myArr;
myObj.length = 3; //max index + 1
myArr = Array.prototype.slice.apply(myObj);
console.log(myArr); //[undefined, ['c', 'd'], ['a', 'b']]
Since ES5 Object.keys() returns an array containing the properties defined directly on an object (excluding properties defined in the prototype chain):
Object.keys(yourObject).map(function(key){ return yourObject[key] });
ES6 takes it one step further with arrow functions:
Object.keys(yourObject).map(key => yourObject[key]);
Nowadays, there is a simple way to do this : Object.values().
var myObj = {
1: [1, 2, 3],
2: [4, 5, 6]
};
console.log(Object.values(myObj));
Output:
[[1, 2, 3], [4, 5, 6]]
This doesn't required jQuery, it's been defined in ECMAScript 2017.
It's supported by every modern browser (forget IE).
The best method would be using a javascript -only function:
var myArr = Array.prototype.slice.call(myObj, 0);
x = [];
for( var i in myObj ) {
x[i] = myObj[i];
}
ECMASCRIPT 5:
Object.keys(myObj).map(function(x) { return myObj[x]; })
ECMASCRIPT 2015 or ES6:
Object.keys(myObj).map(x => myObj[x])
How about jQuery.makeArray(obj)
This is how I did it in my app.
ES8 way made easy:
The official documentation
const obj = { x: 'xxx', y: 1 };
let arr = Object.values(obj); // ['xxx', 1]
console.log(arr);
The solving is very simple
var my_obj = {1:[Array-Data], 2:[Array-Data]}
Object.keys(my_obj).map(function(property_name){
return my_obj[property_name];
});
Fiddle Demo
Extension to answer of bjornd .
var myObj = {
1: [1, [2], 3],
2: [4, 5, [6]]
}, count = 0,
i;
//count the JavaScript object length supporting IE < 9 also
for (i in myObj) {
if (myObj.hasOwnProperty(i)) {
count++;
}
}
//count = Object.keys(myObj).length;// but not support IE < 9
myObj.length = count + 1; //max index + 1
myArr = Array.prototype.slice.apply(myObj);
console.log(myArr);
Reference
Array.prototype.slice()
Function.prototype.apply()
Object.prototype.hasOwnProperty()
Object.keys()
If you want to keep the name of the object's properties as values. Example:
var fields = {
Name: { type: 'string', maxLength: 50 },
Age: { type: 'number', minValue: 0 }
}
Use Object.keys(), Array.map() and Object.assign():
var columns = Object.keys( fields ).map( p => Object.assign( fields[p], {field:p} ) )
Result:
[ { field: 'Name', type: 'string', maxLength: 50 },
{ field: 'Age', type: 'number', minValue: 0 } ]
Explanation:
Object.keys() enumerates all the properties of the source ; .map() applies the => function to each property and returns an Array ; Object.assign() merges name and value for each property.
I made a custom function:
Object.prototype.toArray=function(){
var arr=new Array();
for( var i in this ) {
if (this.hasOwnProperty(i)){
arr.push(this[i]);
}
}
return arr;
};
After some tests, here is a general object to array function convertor:
You have the object:
var obj = {
some_key_1: "some_value_1"
some_key_2: "some_value_2"
};
The function:
function ObjectToArray(o)
{
var k = Object.getOwnPropertyNames(o);
var v = Object.values(o);
var c = function(l)
{
this.k = [];
this.v = [];
this.length = l;
};
var r = new c(k.length);
for (var i = 0; i < k.length; i++)
{
r.k[i] = k[i];
r.v[i] = v[i];
}
return r;
}
Function Use:
var arr = ObjectToArray(obj);
You Get:
arr {
key: [
"some_key_1",
"some_key_2"
],
value: [
"some_value_1",
"some_value_2"
],
length: 2
}
So then you can reach all keys & values like:
for (var i = 0; i < arr.length; i++)
{
console.log(arr.key[i] + " = " + arr.value[i]);
}
Result in console:
some_key_1 = some_value_1
some_key_2 = some_value_2
Edit:
Or in prototype form:
Object.prototype.objectToArray = function()
{
if (
typeof this != 'object' ||
typeof this.length != "undefined"
) {
return false;
}
var k = Object.getOwnPropertyNames(this);
var v = Object.values(this);
var c = function(l)
{
this.k = [];
this.v = [];
this.length = l;
};
var r = new c(k.length);
for (var i = 0; i < k.length; i++)
{
r.k[i] = k[i];
r.v[i] = v[i];
}
return r;
};
And then use like:
console.log(obj.objectToArray);
You can create a simple function to do the conversion from object to array, something like this can do the job for you using pure javascript:
var objectToArray = function(obj) {
var arr = [];
if ('object' !== typeof obj || 'undefined' === typeof obj || Array.isArray(obj)) {
return obj;
} else {
Object.keys(obj).map(x=>arr.push(obj[x]));
}
return arr;
};
or this one:
var objectToArray = function(obj) {
var arr =[];
for(let o in obj) {
if (obj.hasOwnProperty(o)) {
arr.push(obj[o]);
}
}
return arr;
};
and call and use the function as below:
var obj = {1:'a', 2:'b', 3:'c', 4:'d', 5:'e'};
objectToArray(obj); // return ["a", "b", "c", "d", "e"]
Also in the future we will have something called Object.values(obj), similar to Object.keys(obj) which will return all properties for you as an array, but not supported in many browsers yet...

Converting a JS object to an array using jQuery

My application creates a JavaScript object, like the following:
myObj= {1:[Array-Data], 2:[Array-Data]}
But I need this object as an array.
array[1]:[Array-Data]
array[2]:[Array-Data]
So I tried to convert this object to an array by iterating with $.each through the object and adding the element to an array:
x=[]
$.each(myObj, function(i,n) {
x.push(n);});
Is there an better way to convert an object to an array or maybe a function?
If you are looking for a functional approach:
var obj = {1: 11, 2: 22};
var arr = Object.keys(obj).map(function (key) { return obj[key]; });
Results in:
[11, 22]
The same with an ES6 arrow function:
Object.keys(obj).map(key => obj[key])
With ES7 you will be able to use Object.values instead (more information):
var arr = Object.values(obj);
Or if you are already using Underscore/Lo-Dash:
var arr = _.values(obj)
var myObj = {
1: [1, 2, 3],
2: [4, 5, 6]
};
var array = $.map(myObj, function(value, index) {
return [value];
});
console.log(array);
Output:
[[1, 2, 3], [4, 5, 6]]
Simply do
Object.values(obj);
That's all!
I think you can use for in but checking if the property is not inerithed
myObj= {1:[Array-Data], 2:[Array-Data]}
var arr =[];
for( var i in myObj ) {
if (myObj.hasOwnProperty(i)){
arr.push(myObj[i]);
}
}
EDIT - if you want you could also keep the indexes of your object, but you have to check if they are numeric (and you get undefined values for missing indexes:
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
myObj= {1:[1,2], 2:[3,4]}
var arr =[];
for( var i in myObj ) {
if (myObj.hasOwnProperty(i)){
if (isNumber(i)){
arr[i] = myObj[i];
}else{
arr.push(myObj[i]);
}
}
}
If you know the maximum index in you object you can do the following:
var myObj = {
1: ['c', 'd'],
2: ['a', 'b']
},
myArr;
myObj.length = 3; //max index + 1
myArr = Array.prototype.slice.apply(myObj);
console.log(myArr); //[undefined, ['c', 'd'], ['a', 'b']]
Since ES5 Object.keys() returns an array containing the properties defined directly on an object (excluding properties defined in the prototype chain):
Object.keys(yourObject).map(function(key){ return yourObject[key] });
ES6 takes it one step further with arrow functions:
Object.keys(yourObject).map(key => yourObject[key]);
Nowadays, there is a simple way to do this : Object.values().
var myObj = {
1: [1, 2, 3],
2: [4, 5, 6]
};
console.log(Object.values(myObj));
Output:
[[1, 2, 3], [4, 5, 6]]
This doesn't required jQuery, it's been defined in ECMAScript 2017.
It's supported by every modern browser (forget IE).
The best method would be using a javascript -only function:
var myArr = Array.prototype.slice.call(myObj, 0);
x = [];
for( var i in myObj ) {
x[i] = myObj[i];
}
ECMASCRIPT 5:
Object.keys(myObj).map(function(x) { return myObj[x]; })
ECMASCRIPT 2015 or ES6:
Object.keys(myObj).map(x => myObj[x])
How about jQuery.makeArray(obj)
This is how I did it in my app.
ES8 way made easy:
The official documentation
const obj = { x: 'xxx', y: 1 };
let arr = Object.values(obj); // ['xxx', 1]
console.log(arr);
The solving is very simple
var my_obj = {1:[Array-Data], 2:[Array-Data]}
Object.keys(my_obj).map(function(property_name){
return my_obj[property_name];
});
Fiddle Demo
Extension to answer of bjornd .
var myObj = {
1: [1, [2], 3],
2: [4, 5, [6]]
}, count = 0,
i;
//count the JavaScript object length supporting IE < 9 also
for (i in myObj) {
if (myObj.hasOwnProperty(i)) {
count++;
}
}
//count = Object.keys(myObj).length;// but not support IE < 9
myObj.length = count + 1; //max index + 1
myArr = Array.prototype.slice.apply(myObj);
console.log(myArr);
Reference
Array.prototype.slice()
Function.prototype.apply()
Object.prototype.hasOwnProperty()
Object.keys()
If you want to keep the name of the object's properties as values. Example:
var fields = {
Name: { type: 'string', maxLength: 50 },
Age: { type: 'number', minValue: 0 }
}
Use Object.keys(), Array.map() and Object.assign():
var columns = Object.keys( fields ).map( p => Object.assign( fields[p], {field:p} ) )
Result:
[ { field: 'Name', type: 'string', maxLength: 50 },
{ field: 'Age', type: 'number', minValue: 0 } ]
Explanation:
Object.keys() enumerates all the properties of the source ; .map() applies the => function to each property and returns an Array ; Object.assign() merges name and value for each property.
I made a custom function:
Object.prototype.toArray=function(){
var arr=new Array();
for( var i in this ) {
if (this.hasOwnProperty(i)){
arr.push(this[i]);
}
}
return arr;
};
After some tests, here is a general object to array function convertor:
You have the object:
var obj = {
some_key_1: "some_value_1"
some_key_2: "some_value_2"
};
The function:
function ObjectToArray(o)
{
var k = Object.getOwnPropertyNames(o);
var v = Object.values(o);
var c = function(l)
{
this.k = [];
this.v = [];
this.length = l;
};
var r = new c(k.length);
for (var i = 0; i < k.length; i++)
{
r.k[i] = k[i];
r.v[i] = v[i];
}
return r;
}
Function Use:
var arr = ObjectToArray(obj);
You Get:
arr {
key: [
"some_key_1",
"some_key_2"
],
value: [
"some_value_1",
"some_value_2"
],
length: 2
}
So then you can reach all keys & values like:
for (var i = 0; i < arr.length; i++)
{
console.log(arr.key[i] + " = " + arr.value[i]);
}
Result in console:
some_key_1 = some_value_1
some_key_2 = some_value_2
Edit:
Or in prototype form:
Object.prototype.objectToArray = function()
{
if (
typeof this != 'object' ||
typeof this.length != "undefined"
) {
return false;
}
var k = Object.getOwnPropertyNames(this);
var v = Object.values(this);
var c = function(l)
{
this.k = [];
this.v = [];
this.length = l;
};
var r = new c(k.length);
for (var i = 0; i < k.length; i++)
{
r.k[i] = k[i];
r.v[i] = v[i];
}
return r;
};
And then use like:
console.log(obj.objectToArray);
You can create a simple function to do the conversion from object to array, something like this can do the job for you using pure javascript:
var objectToArray = function(obj) {
var arr = [];
if ('object' !== typeof obj || 'undefined' === typeof obj || Array.isArray(obj)) {
return obj;
} else {
Object.keys(obj).map(x=>arr.push(obj[x]));
}
return arr;
};
or this one:
var objectToArray = function(obj) {
var arr =[];
for(let o in obj) {
if (obj.hasOwnProperty(o)) {
arr.push(obj[o]);
}
}
return arr;
};
and call and use the function as below:
var obj = {1:'a', 2:'b', 3:'c', 4:'d', 5:'e'};
objectToArray(obj); // return ["a", "b", "c", "d", "e"]
Also in the future we will have something called Object.values(obj), similar to Object.keys(obj) which will return all properties for you as an array, but not supported in many browsers yet...

Categories