Push multiple elements to array - javascript

I'm trying to push multiple elements as one array, but getting an error:
> a = []
[]
> a.push.apply(null, [1,2])
TypeError: Array.prototype.push called on null or undefined
I'm trying to do similar stuff that I'd do in ruby, I was thinking that apply is something like *.
>> a = []
=> []
>> a.push(*[1,2])
=> [1, 2]

You can push multiple elements into an array in the following way
var a = [];
a.push(1, 2, 3);
console.log(a);

Now in ECMAScript2015 (a.k.a. ES6), you can use the spread operator to append multiple items at once:
var arr = [1];
var newItems = [2, 3];
arr.push(...newItems);
console.log(arr);
See Kangax's ES6 compatibility table to see what browsers are compatible

When using most functions of objects with apply or call, the context parameter MUST be the object you are working on.
In this case, you need a.push.apply(a, [1,2]) (or more correctly Array.prototype.push.apply(a, [1,2]))

As one alternative, you can use Array.concat:
var result = a.concat(b);
This would create and return a new array instead of pushing items to the same array. It can be useful if you don't want to modify the source array but rather make a shallow copy of it.

If you want to add multiple items, you can use Array.push() together with the spread operator:
a = [1,2]
b = [3,4,5,6]
a.push(...b)
The result will be
a === [1,2,3,4,5,6]

If you want an alternative to Array.concat in ECMAScript 2015 (a.k.a. ES6, ES2015) that, like it, does not modify the array but returns a new array you can use the spread operator like so:
var arr = [1];
var newItems = [2, 3];
var newerItems = [4, 5];
var newArr = [...arr, ...newItems, ...newerItems];
console.log(newArr);
Note this is different than the push method as the push method mutates/modifies the array.
If you want to see if certain ES2015 features work in your browser check Kangax's compatibility table.
You can also use Babel or a similar transpiler if you do not want to wait for browser support and want to use ES2015 in production.

Easier way is
a = []
a.push(1,2,3)
Another way is
a = [...a, 4,5,6]
if you want to create another array
const b = a.concat(7,8,9)

I had the same doubt and in my case, an easier solution worked for me:
let array = []
array.push(1, 2, 4, "string", new Object())
console.log(array)
// logs [ 1, 2, 4, 'string', {} ]

Pushing multiple objects at once often depends on how are you declaring your array.
This is how I did
//declaration
productList= [] as any;
now push records
this.productList.push(obj.lenght, obj2.lenght, items);

Imagine you have an array of first ten numbers but missing a number, say 6.
You can insert it into the array at the index 5 with the following code
function insert(array, index, obj) {
return [...array.slice(0,index), obj, ...array.slice(index)]
}
let arr = [1,2,3,4,5,7,8,9,0]
arr = insert(arr, 5, 6)
console.log(arr)

Related

How can I "unshift" a 1D array into each el of a 2D array? [duplicate]

I'm trying to push multiple elements as one array, but getting an error:
> a = []
[]
> a.push.apply(null, [1,2])
TypeError: Array.prototype.push called on null or undefined
I'm trying to do similar stuff that I'd do in ruby, I was thinking that apply is something like *.
>> a = []
=> []
>> a.push(*[1,2])
=> [1, 2]
You can push multiple elements into an array in the following way
var a = [];
a.push(1, 2, 3);
console.log(a);
Now in ECMAScript2015 (a.k.a. ES6), you can use the spread operator to append multiple items at once:
var arr = [1];
var newItems = [2, 3];
arr.push(...newItems);
console.log(arr);
See Kangax's ES6 compatibility table to see what browsers are compatible
When using most functions of objects with apply or call, the context parameter MUST be the object you are working on.
In this case, you need a.push.apply(a, [1,2]) (or more correctly Array.prototype.push.apply(a, [1,2]))
As one alternative, you can use Array.concat:
var result = a.concat(b);
This would create and return a new array instead of pushing items to the same array. It can be useful if you don't want to modify the source array but rather make a shallow copy of it.
If you want to add multiple items, you can use Array.push() together with the spread operator:
a = [1,2]
b = [3,4,5,6]
a.push(...b)
The result will be
a === [1,2,3,4,5,6]
If you want an alternative to Array.concat in ECMAScript 2015 (a.k.a. ES6, ES2015) that, like it, does not modify the array but returns a new array you can use the spread operator like so:
var arr = [1];
var newItems = [2, 3];
var newerItems = [4, 5];
var newArr = [...arr, ...newItems, ...newerItems];
console.log(newArr);
Note this is different than the push method as the push method mutates/modifies the array.
If you want to see if certain ES2015 features work in your browser check Kangax's compatibility table.
You can also use Babel or a similar transpiler if you do not want to wait for browser support and want to use ES2015 in production.
Easier way is
a = []
a.push(1,2,3)
Another way is
a = [...a, 4,5,6]
if you want to create another array
const b = a.concat(7,8,9)
I had the same doubt and in my case, an easier solution worked for me:
let array = []
array.push(1, 2, 4, "string", new Object())
console.log(array)
// logs [ 1, 2, 4, 'string', {} ]
Pushing multiple objects at once often depends on how are you declaring your array.
This is how I did
//declaration
productList= [] as any;
now push records
this.productList.push(obj.lenght, obj2.lenght, items);
Imagine you have an array of first ten numbers but missing a number, say 6.
You can insert it into the array at the index 5 with the following code
function insert(array, index, obj) {
return [...array.slice(0,index), obj, ...array.slice(index)]
}
let arr = [1,2,3,4,5,7,8,9,0]
arr = insert(arr, 5, 6)
console.log(arr)

Difference between fill and fill map

I came across some code which was filling an array of objects like so:
const getObj = () => {
return {a: 1, b: 2, c: 3};
}
const arr = Array(3).fill(null).map(getObj);
console.log(arr);
However, I'm wondering what the main purpose of fill(null).map(getObj) is? It seems redundant as I can simply write the following and get the same resulting array:
const getObj = () => {
return {a: 1, b: 2, c: 3};
}
const arr = Array(3).fill(getObj());
console.log(arr);
So, I'm wondering if these two lines of code do exactly the same thing or if there is something I'm missing?
The resulting arrays (top array first method with fill + map bottom array is only using map):
Array(3).fill(getObj()) will fill your array with references to the same object, Array(3).fill(null).map(getObj) will create object per element. See the example below:
const getObj = () => {
return {a: 1, b: 2, c: 3};
}
const arr = Array(3).fill(null).map(getObj);
arr[0].b=4;
console.log(JSON.stringify(arr));
const arr1 = Array(3).fill(getObj());
arr1[0].b=4;
console.log(JSON.stringify(arr1))
When it comes to Array.fill it is stated in the documentation that:
When fill gets passed an object, it will copy the reference and fill
the array with references to that object.
So using a Array.fill with objects has somewhat limited application unless you really want to have multiple objects pointing to the same reference. In more than few use cases however that would lead to bugs if not understood.
For the 2nd case where you do Array(3).fill(null).map(getObj) this is one of the ways to create a new array based on a given arbitrary size and at the same time fill it with new objects.
The real need for the fill(null) is due to the fact that calling Array(3) would only do one thing. Create a new array and set its length property to 3. That is it!
let arr = Array(3) // returns new array with its "length" property set to 3
console.log(arr) // [empty × 3] <-- browser console
So that array now has only length and bunch of empty elements. You can't do much with it until it actually has values. Therefore the need for fill so that you give it any value and then map through it to set the values you actually want. Using Array.map and calling each iteration your function guarantees you do not have same references. You could have skipped the fill step and done something like this:
const getObj = () => ({a: 1, b: 2, c: 3})
// using array destructuring
let arr = [...Array(3)].map(getObj)
arr[0].a = 3
console.log(arr)
// using Array.from
let arr2 = Array.from(Array(3)).map(getObj)
arr2[0].a = 3
console.log(arr2)
There are somewhat shorter and get you the exact same result of filling the array with specified length with objects and not references to the same object.
The trick here is that both would "fill" the array after it is defined with undefined values instead, after which the map would fill it with the values we want.

JavaScript Array.concat and push workaround

It's always tricky to think Array.concat thing. Often, I just want to use mutable Array.push because I simply add extra-data on the immutable data. So, I usually do:
array[array.length] = newData;
I've asked a question related got some answers here: How to store data of a functional chain
const L = (a) => {
const m = a => (m.list ? m.list : m.list = [])
.push(a) && m;
//use `concat` and refactor needed instead of `push`
//that is not immutable
return m(a); // Object construction!
};
console.log(L);
console.log(L(2));
console.log(L(1)(2)(3))
some outputs:
{ [Function: m] list: [ 2 ] }
{ [Function: m] list: [ 1, 2, 3 ] }
I feel that push should be replaced with using concat, but still, push makes the code elegant simply because we don't want to prepare another object here.
Basically, I want to do:
arr1 = arr1.concat(arr2);
but, is there any way to write
arr1[arr1.length] = arr2;
which ends up with a nested array, and does not work.
You could assign a new array with a default array for not given m.list.
const L = (a) => {
const m = a => (m.list = (m.list || []).concat(a), m);
return m(a);
};
console.log(L.list);
console.log(L(2).list);
console.log(L(1)(2)(3).list);
You can use multiple parameters in Array.push so:
var a = [];
a.push(3, 4) // a is now [3, 4]
Combined with the ES6 spread syntax:
var a = [1, 2];
var b = [3, 4]
a.push(...b); // a is now [1, 2, 3, 4]
arr1[arr1.length] represents a single value, the value at index arr1.length.
Imagine this array
[ 1 , 2 , 3 , 4 ] // arr of length 4
^0 ^1 ^2 ^3 // indexes
If we say arr1[arr1.length] = someThing
We ask javascript to put something right here, and only here, at index 4:
[ 1 , 2 , 3 , 4 , ] // arr of length 4
^0 ^1 ^2 ^3 ^4 // add someThing in index 4
So, if we want to add something strictly with arr1[arr1.length], then we need to keep doing that for each index. for each meaning any kind of loop. E.G:
// Not recommended to use
var arr1 = [1,2,3];
var arr2 = [3,4,5];
while (arr2.length){
arr1[arr1.length] = arr2.shift();
}
console.log(arr1); // [1,2,3,3,4,5]
console.log(arr2); // []
But, as you can see, this method, or any similar one, even if optimized, is not the right approach. You need a concatenation.
Since you mention a functional one, which returns the resulting array, you can simply replace the initial array and make use of spread operator:
var arr1 = [1,2,3];
var arr2 = [3,4,5];
console.log(arr1 = [...arr1,...arr2]); // [1,2,3,3,4,5]

Create object from an array of objects [duplicate]

In Python one can pass the dict1 constructor a sequence of key-value pairs:
>>> dict([['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']])
{'age': 42, 'name': 'Bob', 'breakfast': 'eggs'}
I can't think of any way to do this sort of thing in JavaScript other than defining my own function for the purpose:
function pairs_to_object(pairs) {
var ret = {};
pairs.forEach(function (p) { ret[p[0]] = p[1]; });
return ret;
}
But I'm a JS noob... Is there anything built-in for this sort pairs-to-object conversion?
1 For the purposes of this question, I'm treating Python dicts as Python's counterpart of JS objects, although, of course the similarity is limited only to the fact that they are both key-value collections.
Object.fromEntries does the job. It was added to the language with EcmaScript2019.
If you don't have support for that function, you could define it yourself with the following ES2015 code:
Object.fromEntries = arr => Object.assign({}, ...Array.from(arr, ([k, v]) => ({[k]: v}) ));
A nice thing is that this method does the opposite of Object.entries (ES2017), so now you can go back and forth between the object and array representation:
const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
const obj = Object.fromEntries(arr);
console.log(obj);
// ... and back:
const arr2 = Object.entries(obj);
console.log(arr2); // copy of the original array (omitting duplicate keys)
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES6 Map
There is an alternative to plain objects for key/value pairs: Map.
Its constructor accepts the array-of-pairs format:
// Demo:
const arr = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
const mp = new Map(arr);
// Get one particular value:
console.log(mp.get('age'));
// Get all the keys:
console.log(...mp.keys());
// Get all the values:
console.log(...mp.values());
// Get all the key/value pairs:
console.log(...mp.entries());
If you really need a plain object, then this is not useful, but a Map might present a viable alternative.
You can use the reduce function
x = [[1,2],[3,4],[5,6]];
o = x.reduce(function(prev,curr){prev[curr[0]]=curr[1];return prev;},{})
o is now the equivalent of {1:2, 3:4, 5:6}
If your input array is sparse, you'll want to add a if(curr!=undefined) test on the assignment, but make sure you still return "prev".
If your tuples are something more complex than simple [key,value], you can simply change the way "prev" is assigned to. Eg: prev["key-"+curr[0].toString()]=curr[1]*2;
At the time of writing (2013) JavaScript objects / dictionaries / associative arrays don't have such a constructor natively.
As you said yourself, you can of course build your own function using for instance a functional approach using the reduce function as explained in one of the other answers. A classic for or newer forEach loop would also work, of course. But there isn't anything built-in.
Edit: It's 2019 and now we have Object.fromEntries, which will give you what you need.
Lodash's fromPairs function will do this:
const _ = require('lodash')
const kvPairs = [['a', 1], ['b', 2]]
_.fromPairs(kvPairs)
// => { a: 1, b: 2 }
Object.fromEntries()
There is a method on the Object object called Object.fromEntries(iterable). The iterator object from the iterable object has to produce an array with 2 elements. The first (index 0) array element will be the object key and the second the value.
MDN describes this very accurately:
The Object.fromEntries() method takes a list of key-value pairs and
returns a new object whose properties are given by those entries. The
iterable argument is expected to be an object that implements an
##iterator method, that returns an iterator object, that produces a
two element array-like object, whose first element is a value that
will be used as a property key, and whose second element is the value
to associate with that property key.
How to use:
You don't even need to know the specifics of an iterable object in order to use the Object.fromEntries() method. You can always use the method on the following objects:
2 Dimensional arrays where the inner/nested arrays have 2 elements
Maps
Here is an example:
// map example:
const map = new Map([ ['hi', 'there'], ['foo', 2] ]);
const objFromMap = Object.fromEntries(map);
console.log(objFromMap); // { hi: "there", foo: 2 }
// array example:
const array = [ ['0', '00'], ['1', '11'], ['2', '22'] ];
const objFromArray = Object.fromEntries(array);
console.log(objFromArray); // { 0: "00", 1: "11", 2: "22" }
Caveat, browser compatibility!
At the time of this writing (december 2019) this method is relatively new and not implemented by all browsers. In order to use this method and to ensure that you JS code will run in all browsers you might have to transpile your code to a earlier version of JS.
Javascript does not have a native function for converting an array into an object in the way you have described. But, this is because there is no need for it. You have already included in the question an example solution, where you define the function yourself, but that really isn't necessary. As long as you can be sure that the input array is correct, you could even do the conversion with a simple for loop, like so:
var input = [['name', 'Bob'], ['age', 42], ['breakfast', 'eggs']];
var output = {};
for(i in input) output[input[i][0]] = input[i][1];
Which is just about the most basic code imaginable.
Of course, (as mamapitufo points out) it is generally a bad idea to actually use for..in to iterate over an array, because that will also return non-indexes as values of i. Still, the point is that this kind of operation is too simple, and too rarely needed, to justify having a native function.
The python dict is a structure which is not needed in javascript, because the two languages have different approaches to typing, and to design in general, and so what is useful to one is not useful to another. While you could work on using the same methods and structures that you used in python, it might be a better idea to think about how to take advantage of javascript's different way of doing things - maybe you will find that you don't need a dict after all.
const sampleArr = ['foo', 'bar', 'baz', 42];
const _chunk = (arr, chunkSize, chunks = []) => {
while (arr.length) {
chunks = [...chunks, arr.splice(0, chunkSize)];
}
return chunks;
}; //splice array to chunks
const arr = _chunk(sampleArr, 2);
const entries = new Map([...arr]);
const obj = Object.fromEntries(entries);
console.log(obj)
// expected output: Object { foo: "bar", baz: 42 }

How to get value at a specific index of array In JavaScript?

I have an array and simply want to get the element at index 1.
var myValues = new Array();
var valueAtIndex1 = myValues.getValue(1); // (something like this)
How can I get the value at the 1st index of my array in JavaScript?
You can access an element at a specific index using the bracket notation accessor.
var valueAtIndex1 = myValues[1];
On newer browsers/JavaScript engines (see browser compatibility here), you can also use the .at() method on arrays.
var valueAtIndex1 = myValues.at(1);
On positive indexes, both methods work the same (the first one being more common). Array.prototype.at() however allows you to access elements starting from the end of the array by passing a negative number. Passing -1 will give the last element of the array, passing -2 the second last, etc.
See more details at the MDN documentation.
Array indexes in JavaScript start at zero for the first item, so try this:
var firstArrayItem = myValues[0]
Of course, if you actually want the second item in the array at index 1, then it's myValues[1].
See Accessing array elements for more info.
You can just use []:
var valueAtIndex1 = myValues[1];
indexer (array[index]) is the most frequent use. An alternative is at array method:
const cart = ['apple', 'banana', 'pear'];
cart.at(0) // 'apple'
cart.at(2) // 'pear'
If you come from another programming language, maybe it looks more familiar.
shift can be used in places where you want to get the first element (index=0) of an array and chain with other array methods.
example:
const comps = [{}, {}, {}]
const specComp = comps
.map(fn1)
.filter(fn2)
.shift()
Remember shift mutates the array, which is very different from accessing via an indexer.
Update 2022
With ES2022 you can use Array.prototype.at():
const myValues = [1, 2, 3]
myValues.at(1) // 2
at() also supports negative index, which returns an element from the end of the array:
const myValues = [1, 2, 3]
myValues.at(-1) // 3
myValues.at(-2) // 2
Read more:
MDN, JavascriptTutorial, Specifications
You can use [];
var indexValue = Index[1];
As you specifically want to get the element at index 1. You can also achieve this by using Array destructuring from ES6.
const arr = [1, 2, 3, 4];
const [zeroIndex, firstIndex, ...remaining] = arr;
console.log(firstIndex); // 2
Or, As per ES2022. You can also use Array.at()
const arr = [1, 2, 3, 4];
console.log(arr.at(1)); // 2

Categories

Resources