This sounds like a simple task, but I can't quite figure it out: I have an array :
var array = ['opt1','sub1','subsub1','subsubsub1']
From that I want to generate the following objects:
{
opt1:{
sub1:{
subsub1:{
subsubsub1:{}
}
}
}
}
I have a way to do it, making a string and using eval, but I'm looking to avoid that, any idea?
You could use reduce:
var array = ['opt1','sub1','subsub1','subsubsub1'];
var object = {};
array.reduce(function(o, s) { return o[s] = {}; }, object);
console.log(object);
But this was only introduced in ECMAScript 5.1, so it won't be supported in some older browsers. If you want something that will be supported by legacy browsers, you could use the polyfill technique described in the MDN article above, or a simple for-loop, like this:
var array = ['opt1','sub1','subsub1','subsubsub1'];
var object = {}, o = object;
for(var i = 0; i < array.length; i++) {
o = o[array[i]] = {};
}
console.log(object);
You can use reduceRight to transform the array into a 'chain' of objects:
const array = ['a', 'b', 'c'];
const object = array.reduceRight((obj, next) => ({[next]: obj}), {});
// Example:
console.log(object); // {"a":{"b":{"c":{}}}}
you could use lodash set function
_.set(yourObject, 'a.b.c')
You can use the following Function
function arr2nestedObject(myArray){
var cp_myArray = myArray;
var lastobj = {};
while(cp_myArray.length>0){
newobj = {};
var prop = cp_myArray.pop();
newobj[prop] = lastobj;
lastobj = newobj;
}
return lastobj;
}
The following code:
var myArray = ["personal-information", "address", "street",'Great-Success'];
console.log(JSON.stringify(arr2nestedObject(myArray),undefined,2));
Would Produce the Following Output:
{
"personal-information": {
"address": {
"street": {
"Great-Success": {}
}
}
}
}
Please let me know if that was what you meant.
Kind Regards.
As #p.s.w.g answer is a very good answer with pure js, but if you want an alternative with in a descriptive and functional way of that and set a value for final nested prop, you can use ramdajs assocPath https://ramdajs.com/docs/#assocPath like below:
var array = ['opt1','sub1','subsub1','subsubsub1'];
R.assocPath(array, "the value", {});
more details:
Makes a shallow clone of an object, setting or overriding the nodes
required to create the given path, and placing the specific value at
the tail end of that path. Note that this copies and flattens
prototype properties onto the new object as well. All non-primitive
properties are copied by reference.
examples:
R.assocPath(['a', 'b', 'c'], 42, {a: {b: {c: 0}}}); //=> {a: {b: {c: 42}}}
// Any missing or non-object keys in path will be overridden
R.assocPath(['a', 'b', 'c'], 42, {a: 5}); //=> {a: {b: {c: 42}}}
Related
If I have a JS object, and I'd like to create a new object which copies over all properties except for a blacklist of properties that need to be filtered out, what's the simplest way to do it?
So I would do something like
originalObject.copyAndFilter('a', 'b')
Which would take the original object, copy it, and make sure properties a and b aren't in the new object.
I'm using ES2015/2016 through Babel so if it provides an even simpler way that would work too.
You could use Set and delete the unwanted properties.
var object = { a: 1, b: 2, c: 3, d: 4 },
filteredObject = {},
p = new Set(Object.keys(object));
blacklist = ['a', 'b'];
blacklist.forEach(a => p.delete(a));
[...p].forEach(k => filteredObject[k] = object[k]);
console.log(filteredObject);
Well, there's no simple native way to do it, I would convert the keys to an array, filter it, then create a new object:
const obj = {a: 'foo', b: 'bar', c: 'baz'};
const blacklist = ['a', 'b'];
const keys = Object.keys(obj);
const filteredKeys = keys.filter(key => !blacklist.includes(key));
const filteredObj = filteredKeys.reduce((result, key) => {
result[key] = obj[key];
return result;
}, {});
console.log(filteredObj);
You can just loop over object keys and create a new object. You can even use for...in for it. This will have added advantage of being supported in all browsers.
var obj = {a: 'foo', b: 'bar', c: 'baz'};
var blackListKeys = ['a', 'b','z'];
var obj2 = {}
for(var k in obj){
if(blackListKeys.indexOf(k) === -1)
obj2[k] = obj[k];
}
console.log(obj2)
var obj = {foo: 1, a: 2, b:3}
var newObj = {}
var blacklist = ['a', 'b']
for(let [key, value] of Object.entries(obj)) {
!blacklist.includes(key) && (newObj[key] = value)
}
console.log(newObj)
With fewer variables:
var obj = {foo: 1, a: 2, b: 3}
var newObj = Object.entries(obj)
.filter(([key, val]) => !['a', 'b'].includes(key))
.reduce((newObj, [key, value]) => (newObj[key] = value, newObj), {})
console.log(newObj)
Here there are two problems:
First one is actually copying the object without references.
If you simply loop against object keys and perform assignments of its values from the original object, if that values are also objects, you end up referencing that objects (or even arrays), not copying itself. So you will need to detect that and recursively call your copy_object function to avoid references.
Fortunately that problem is already solved in some libraries which provides an object extend() function like npm (server side) and jQuery (browser).
The trick consist only on extending new freshly created object:
var dst_object = extend({}, src_object);
The second problem is to avoid undesired keys.
Here there are to possible approaches: One is to fully reimplement beforementioned extend() function in a way that they provide a blacklist functionality.
...and the second (and less error prone) is to simply drop undesired keys after copying the object. If they aren't huge data structures, the overhead will be insignificant.
Example:
// npm install --save extend
var extend = require("extend");
function oClone(target, blacklist) {
var dest = extend({}, target);
if (blacklist) {
for (var i=0; i<blacklist.length; i++) {
delete (dest[blacklist[i]]);
};
};
return dest;
};
I think Object.assign is the best ES5 utility to make this with little extra logic:
function copyAndFilter(...args){
var copy = Object.assign( {} , this);
args.forEach(prop => {
delete copy[prop];
}); return copy;
}
Then:
var a = {foo : 'foo' , bar : 'bar'};
a.copyAndFilter = /* function definition above*/
a.copyAndFilter('foo');// { bar : 'bar' }
Is it possible to create a function magic() that would turn this:
[{a:1}, {b:2}, magic(), {e:5}]
into:
[{a:1}, {b:2}, {c:3}, {d:4}, {e:5}]
Not with that precise syntax, no. You can get really close in ES2015, but not exactly identical (in ES5 and earlier, you can't really get close).
In ES2015 ("ES6") and later, you can make magic return any iterable (like an array), and use it with spread notation:
let a = [{a:1}, {b:2}, ...magic(), {e:5}];
// Spread notation ----^^^
Example:
// REQUIRES ES2015+ SUPPORT
function magic() {
return [{c: 3}, {d: 4}];
}
let array = [{a:1}, {b:2}, ...magic(), {e:5}];
console.log(array);
In ES5 and earlier, you can make magic return an array and use concat:
var array = [{a:1}, {b:2}].concat(magic()).concat([{e:5}]);
Example:
function magic() {
return [{c: 3}, {d: 4}];
}
var array = [{a:1}, {b:2}].concat(magic()).concat([{e:5}]);
console.log(array);
That's not hyper-efficient as it creates and throws away a couple of temporary arrays, but 99.99% of the time, you don't care.
No you cant, as magic doesn't know the array.
You could do something similar by passing the array and returning one in the function.
var arr = [{a:1}, {b:2},{e:5}];
arr = magic(arr); // do your magic
Another way which would work is adding magic to to Array.prototype
Array.prototype.magic = function(){
// do your magic
};
var arr = [{a:1}, {b:2},{e:5}].magic();
#Johannes Merz is right. You can not do it while the array is being constructed. But guess what? If you can shift the operation to the asynchronous / retarded timeline then yes you can. Lets see...
function magic(){
setTimeout(_ => {
var idx = arr.indexOf(arguments.callee.name);
arr.splice(idx,1);
arr.splice(idx,0,{c:3},{d:4});
console.log(arr);
},0);
return arguments.callee.name;
}
var arr = [{a:1},{b:2},magic(),{e:5}];
How can I add an object to an array (in javascript or jquery)?
For example, what is the problem with this code?
function() {
var a = new array();
var b = new object();
a[0] = b;
}
I would like to use this code to save many objects in the array of function1 and call function2 to use the object in the array.
How can I save an object in an array?
How can I put an object in an array and save it to a variable?
Put anything into an array using Array.push().
var a=[], b={};
a.push(b);
// a[0] === b;
Extra information on Arrays
Add more than one item at a time
var x = ['a'];
x.push('b', 'c');
// x = ['a', 'b', 'c']
Add items to the beginning of an array
var x = ['c', 'd'];
x.unshift('a', 'b');
// x = ['a', 'b', 'c', 'd']
Add the contents of one array to another
var x = ['a', 'b', 'c'];
var y = ['d', 'e', 'f'];
x.push.apply(x, y);
// x = ['a', 'b', 'c', 'd', 'e', 'f']
// y = ['d', 'e', 'f'] (remains unchanged)
Create a new array from the contents of two arrays
var x = ['a', 'b', 'c'];
var y = ['d', 'e', 'f'];
var z = x.concat(y);
// x = ['a', 'b', 'c'] (remains unchanged)
// y = ['d', 'e', 'f'] (remains unchanged)
// z = ['a', 'b', 'c', 'd', 'e', 'f']
var years = [];
for (i= 2015;i<=2030;i=i+1){
years.push({operator : i})
}
here array years is having values like
years[0]={operator:2015}
years[1]={operator:2016}
it continues like this.
First of all, there is no object or array. There are Object and Array. Secondly, you can do that:
a = new Array();
b = new Object();
a[0] = b;
Now a will be an array with b as its only element.
Using ES6 notation, you can do something like this:
For appending you can use the spread operator like this:
var arr1 = [1,2,3]
var obj = 4
var newData = [...arr1, obj] // [1,2,3,4]
console.log(newData);
JavaScript is case-sensitive. Calling new array() and new object() will throw a ReferenceError since they don't exist.
It's better to avoid new Array() due to its error-prone behavior.
Instead, assign the new array with = [val1, val2, val_n]. For objects, use = {}.
There are many ways when it comes to extending an array (as shown in John's answer) but the safest way would be just to use concat instead of push. concat returns a new array, leaving the original array untouched. push mutates the calling array which should be avoided, especially if the array is globally defined.
It's also a good practice to freeze the object as well as the new array in order to avoid unintended mutations. A frozen object is neither mutable nor extensible (shallowly).
Applying those points and to answer your two questions, you could define a function like this:
function appendObjTo(thatArray, newObj) {
const frozenObj = Object.freeze(newObj);
return Object.freeze(thatArray.concat(frozenObj));
}
Usage:
// Given
const myArray = ["A", "B"];
// "save it to a variable"
const newArray = appendObjTo(myArray, {hello: "world!"});
// returns: ["A", "B", {hello: "world!"}]. myArray did not change.
/* array literal */
var aData = [];
/* object constructur */
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
this.fullname = function() {
// return (this.firstname + " " + this.lastname);
return (`${this.firstname} ${this.lastname}`); // es6 template string
};
}
/* store object into array */
aData[aData.length] = new Person("Java", "Script"); // aData[0]
aData.push(new Person("John", "Doe"));
aData.push(new Person("Anna", "Smith"));
aData.push(new Person("Black", "Pearl"));
aData[aData.length] = new Person("stack", "overflow"); // aData[4]
/* loop array */
for (var i in aData) {
alert(aData[i].fullname());
}
/* convert array of object into string json */
var jsonString = JSON.stringify(aData);
document.write(jsonString);
Push object into array
With push you can even add multiple objects to an array
let myArray = [];
myArray.push(
{name:"James", dataType:TYPES.VarChar, Value: body.Name},
{name:"Boo", dataType:TYPES.VarChar, Value: body.Name},
{name:"Alina", dataType:TYPES.VarChar, Value: body.Name}
);
Expanding Gabi Purcaru's answer to include an answer to number 2.
a = new Array();
b = new Object();
a[0] = b;
var c = a[0]; // c is now the object we inserted into a...
obejct is clearly a typo. But both object and array need capital letters.
You can use short hands for new Array and new Object these are [] and {}
You can push data into the array using .push. This adds it to the end of the array. or you can set an index to contain the data.
function saveToArray() {
var o = {};
o.foo = 42;
var arr = [];
arr.push(o);
return arr;
}
function other() {
var arr = saveToArray();
alert(arr[0]);
}
other();
You can use with Spread Operator (...) like this:
let arr = [{num: 1, char: "a"}, {num: 2, char: "b"}];
arr = [...arr,{num: 3, char: "c"}];
//...arr --> spread operator
console.log(arr);
On alternativ answer is this.
if you have and array like this: var contacts = [bob, mary];
and you want to put another array in this array, you can do that in this way:
Declare the function constructor
function add (firstName,lastName,email,phoneNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.phoneNumber = phoneNumber;
}
make the object from the function:
var add1 = new add("Alba","Fas","Des#gmail.com","[098] 654365364");
and add the object in to the array:
contacts[contacts.length] = add1;
a=[];
a.push(['b','c','d','e','f']);
The way I made object creator with auto list:
var list = [];
function saveToArray(x) {
list.push(x);
};
function newObject () {
saveToArray(this);
};
Performance
Today 2020.12.04 I perform tests on MacOs HighSierra 10.13.6 on Chrome v86, Safari v13.1.2 and Firefox v83 for chosen solutions.
Results
For all browsers
in-place solution based on length (B) is fastest for small arrays, and in Firefox for big too and for Chrome and Safari is fast
in-place solution based on push (A) is fastest for big arrays on Chrome and Safari, and fast for Firefox and small arrays
in-place solution C is slow for big arrays and medium fast for small
non-in-place solutions D and E are slow for big arrays
non-in-place solutions E,F and D(on Firefox) are slow for small arrays
Details
I perform 2 tests cases:
for small array with 10 elements - you can run it HERE
for big array with 1M elements - you can run it HERE
Below snippet presents differences between solutions
A,
B,
C,
D,
E,
F
PS: Answer B was deleted - but actually it was the first answer which use this technique so if you have access to see it please click on "undelete".
// https://stackoverflow.com/a/6254088/860099
function A(a,o) {
a.push(o);
return a;
}
// https://stackoverflow.com/a/47506893/860099
function B(a,o) {
a[a.length] = o;
return a;
}
// https://stackoverflow.com/a/6254088/860099
function C(a,o) {
return a.concat(o);
}
// https://stackoverflow.com/a/50933891/860099
function D(a,o) {
return [...a,o];
}
// https://stackoverflow.com/a/42428064/860099
function E(a,o) {
const frozenObj = Object.freeze(o);
return Object.freeze(a.concat(frozenObj));
}
// https://stackoverflow.com/a/6254088/860099
function F(a,o) {
a.unshift(o);
return a;
}
// -------
// TEST
// -------
[A,B,C,D,E,F].map(f=> {
console.log(`${f.name} ${JSON.stringify(f([1,2],{}))}`)
})
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!
And here are example results for chrome
You are running into a scope problem if you use your code as such. You have to declare it outside the functions if you plan to use it between them (or if calling, pass it as a parameter).
var a = new Array();
var b = new Object();
function first() {
a.push(b);
// Alternatively, a[a.length] = b
// both methods work fine
}
function second() {
var c = a[0];
}
// code
first();
// more code
second();
// even more code
I would like to get the keys of a JavaScript object as an array, either in jQuery or pure JavaScript.
Is there a less verbose way than this?
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
keys.push(key);
}
Use Object.keys:
var foo = {
'alpha': 'puffin',
'beta': 'beagle'
};
var keys = Object.keys(foo);
console.log(keys) // ['alpha', 'beta']
// (or maybe some other order, keys are unordered).
This is an ES5 feature. This means it works in all modern browsers but will not work in legacy browsers.
The ES5-shim has a implementation of Object.keys you can steal
You can use jQuery's $.map.
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
return i;
});
Of course, Object.keys() is the best way to get an Object's keys. If it's not available in your environment, it can be trivially shimmed using code such as in your example (except you'd need to take into account your loop will iterate over all properties up the prototype chain, unlike Object.keys()'s behaviour).
However, your example code...
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
keys.push(key);
}
jsFiddle.
...could be modified. You can do the assignment right in the variable part.
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [], i = 0;
for (keys[i++] in foo) {}
jsFiddle.
Of course, this behaviour is different to what Object.keys() actually does (jsFiddle). You could simply use the shim on the MDN documentation.
In case you're here looking for something to list the keys of an n-depth nested object as a flat array:
const getObjectKeys = (obj, prefix = '') => {
return Object.entries(obj).reduce((collector, [key, val]) => {
const newKeys = [ ...collector, prefix ? `${prefix}.${key}` : key ]
if (Object.prototype.toString.call(val) === '[object Object]') {
const newPrefix = prefix ? `${prefix}.${key}` : key
const otherKeys = getObjectKeys(val, newPrefix)
return [ ...newKeys, ...otherKeys ]
}
return newKeys
}, [])
}
console.log(getObjectKeys({a: 1, b: 2, c: { d: 3, e: { f: 4 }}}))
I don't know about less verbose but I was inspired to coerce the following onto one line by the one-liner request, don't know how Pythonic it is though ;)
var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
Summary
For getting all of the keys of an Object you can use Object.keys(). Object.keys() takes an object as an argument and returns an array of all the keys.
Example:
const object = {
a: 'string1',
b: 42,
c: 34
};
const keys = Object.keys(object)
console.log(keys);
console.log(keys.length) // we can easily access the total amount of properties the object has
In the above example we store an array of keys in the keys const. We then can easily access the amount of properties on the object by checking the length of the keys array.
Getting the values with: Object.values()
The complementary function of Object.keys() is Object.values(). This function takes an object as an argument and returns an array of values. For example:
const object = {
a: 'random',
b: 22,
c: true
};
console.log(Object.values(object));
Year 2022 and JavaScript still does not have a sound way to work with hashes?
This issues a warning but works:
Object.prototype.keys = function() { return Object.keys(this) }
console.log("Keys of an object: ", { a:1, b:2 }.keys() )
// Keys of an object: Array [ "a", "b" ]
// WARN: Line 8:1: Object prototype is read only, properties should not be added no-extend-native
That said, Extending Built-in Objects is Controversial.
If you decide to use Underscore.js you better do
var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
_.each( foo, function( val, key ) {
keys.push(key);
});
console.log(keys);
How can I add an object to an array (in javascript or jquery)?
For example, what is the problem with this code?
function() {
var a = new array();
var b = new object();
a[0] = b;
}
I would like to use this code to save many objects in the array of function1 and call function2 to use the object in the array.
How can I save an object in an array?
How can I put an object in an array and save it to a variable?
Put anything into an array using Array.push().
var a=[], b={};
a.push(b);
// a[0] === b;
Extra information on Arrays
Add more than one item at a time
var x = ['a'];
x.push('b', 'c');
// x = ['a', 'b', 'c']
Add items to the beginning of an array
var x = ['c', 'd'];
x.unshift('a', 'b');
// x = ['a', 'b', 'c', 'd']
Add the contents of one array to another
var x = ['a', 'b', 'c'];
var y = ['d', 'e', 'f'];
x.push.apply(x, y);
// x = ['a', 'b', 'c', 'd', 'e', 'f']
// y = ['d', 'e', 'f'] (remains unchanged)
Create a new array from the contents of two arrays
var x = ['a', 'b', 'c'];
var y = ['d', 'e', 'f'];
var z = x.concat(y);
// x = ['a', 'b', 'c'] (remains unchanged)
// y = ['d', 'e', 'f'] (remains unchanged)
// z = ['a', 'b', 'c', 'd', 'e', 'f']
var years = [];
for (i= 2015;i<=2030;i=i+1){
years.push({operator : i})
}
here array years is having values like
years[0]={operator:2015}
years[1]={operator:2016}
it continues like this.
First of all, there is no object or array. There are Object and Array. Secondly, you can do that:
a = new Array();
b = new Object();
a[0] = b;
Now a will be an array with b as its only element.
Using ES6 notation, you can do something like this:
For appending you can use the spread operator like this:
var arr1 = [1,2,3]
var obj = 4
var newData = [...arr1, obj] // [1,2,3,4]
console.log(newData);
JavaScript is case-sensitive. Calling new array() and new object() will throw a ReferenceError since they don't exist.
It's better to avoid new Array() due to its error-prone behavior.
Instead, assign the new array with = [val1, val2, val_n]. For objects, use = {}.
There are many ways when it comes to extending an array (as shown in John's answer) but the safest way would be just to use concat instead of push. concat returns a new array, leaving the original array untouched. push mutates the calling array which should be avoided, especially if the array is globally defined.
It's also a good practice to freeze the object as well as the new array in order to avoid unintended mutations. A frozen object is neither mutable nor extensible (shallowly).
Applying those points and to answer your two questions, you could define a function like this:
function appendObjTo(thatArray, newObj) {
const frozenObj = Object.freeze(newObj);
return Object.freeze(thatArray.concat(frozenObj));
}
Usage:
// Given
const myArray = ["A", "B"];
// "save it to a variable"
const newArray = appendObjTo(myArray, {hello: "world!"});
// returns: ["A", "B", {hello: "world!"}]. myArray did not change.
/* array literal */
var aData = [];
/* object constructur */
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
this.fullname = function() {
// return (this.firstname + " " + this.lastname);
return (`${this.firstname} ${this.lastname}`); // es6 template string
};
}
/* store object into array */
aData[aData.length] = new Person("Java", "Script"); // aData[0]
aData.push(new Person("John", "Doe"));
aData.push(new Person("Anna", "Smith"));
aData.push(new Person("Black", "Pearl"));
aData[aData.length] = new Person("stack", "overflow"); // aData[4]
/* loop array */
for (var i in aData) {
alert(aData[i].fullname());
}
/* convert array of object into string json */
var jsonString = JSON.stringify(aData);
document.write(jsonString);
Push object into array
With push you can even add multiple objects to an array
let myArray = [];
myArray.push(
{name:"James", dataType:TYPES.VarChar, Value: body.Name},
{name:"Boo", dataType:TYPES.VarChar, Value: body.Name},
{name:"Alina", dataType:TYPES.VarChar, Value: body.Name}
);
Expanding Gabi Purcaru's answer to include an answer to number 2.
a = new Array();
b = new Object();
a[0] = b;
var c = a[0]; // c is now the object we inserted into a...
obejct is clearly a typo. But both object and array need capital letters.
You can use short hands for new Array and new Object these are [] and {}
You can push data into the array using .push. This adds it to the end of the array. or you can set an index to contain the data.
function saveToArray() {
var o = {};
o.foo = 42;
var arr = [];
arr.push(o);
return arr;
}
function other() {
var arr = saveToArray();
alert(arr[0]);
}
other();
You can use with Spread Operator (...) like this:
let arr = [{num: 1, char: "a"}, {num: 2, char: "b"}];
arr = [...arr,{num: 3, char: "c"}];
//...arr --> spread operator
console.log(arr);
On alternativ answer is this.
if you have and array like this: var contacts = [bob, mary];
and you want to put another array in this array, you can do that in this way:
Declare the function constructor
function add (firstName,lastName,email,phoneNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.phoneNumber = phoneNumber;
}
make the object from the function:
var add1 = new add("Alba","Fas","Des#gmail.com","[098] 654365364");
and add the object in to the array:
contacts[contacts.length] = add1;
a=[];
a.push(['b','c','d','e','f']);
The way I made object creator with auto list:
var list = [];
function saveToArray(x) {
list.push(x);
};
function newObject () {
saveToArray(this);
};
Performance
Today 2020.12.04 I perform tests on MacOs HighSierra 10.13.6 on Chrome v86, Safari v13.1.2 and Firefox v83 for chosen solutions.
Results
For all browsers
in-place solution based on length (B) is fastest for small arrays, and in Firefox for big too and for Chrome and Safari is fast
in-place solution based on push (A) is fastest for big arrays on Chrome and Safari, and fast for Firefox and small arrays
in-place solution C is slow for big arrays and medium fast for small
non-in-place solutions D and E are slow for big arrays
non-in-place solutions E,F and D(on Firefox) are slow for small arrays
Details
I perform 2 tests cases:
for small array with 10 elements - you can run it HERE
for big array with 1M elements - you can run it HERE
Below snippet presents differences between solutions
A,
B,
C,
D,
E,
F
PS: Answer B was deleted - but actually it was the first answer which use this technique so if you have access to see it please click on "undelete".
// https://stackoverflow.com/a/6254088/860099
function A(a,o) {
a.push(o);
return a;
}
// https://stackoverflow.com/a/47506893/860099
function B(a,o) {
a[a.length] = o;
return a;
}
// https://stackoverflow.com/a/6254088/860099
function C(a,o) {
return a.concat(o);
}
// https://stackoverflow.com/a/50933891/860099
function D(a,o) {
return [...a,o];
}
// https://stackoverflow.com/a/42428064/860099
function E(a,o) {
const frozenObj = Object.freeze(o);
return Object.freeze(a.concat(frozenObj));
}
// https://stackoverflow.com/a/6254088/860099
function F(a,o) {
a.unshift(o);
return a;
}
// -------
// TEST
// -------
[A,B,C,D,E,F].map(f=> {
console.log(`${f.name} ${JSON.stringify(f([1,2],{}))}`)
})
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!
And here are example results for chrome
You are running into a scope problem if you use your code as such. You have to declare it outside the functions if you plan to use it between them (or if calling, pass it as a parameter).
var a = new Array();
var b = new Object();
function first() {
a.push(b);
// Alternatively, a[a.length] = b
// both methods work fine
}
function second() {
var c = a[0];
}
// code
first();
// more code
second();
// even more code