Javascript tracking the differences between elements in an array? - javascript

I have the following simple array:
my_array = [1, 11, 44, 4]
I want to produce a new array consisting of the difference between these elements, so it would be:
diff_array = [10, 33, 40]
What's the best way of going about this?

You could use Array#reduce for iterating and take the absolute delta for pushing to the result array.
Basically you need array.length - 1 deltas and iteration. In this case 3. Reduce takes, if no start value is given, the first two elements and iterates the wanted length. And while it needs the last value for the delta, the last value is returned.
At the end, the returned value of reduce is discarded, becuase it is not used anymore.
1 11 44 4 values
\ / \ / \ /
10 33 40 Math.abs(delta)
var array = [1, 11, 44, 4],
result = [];
array.reduce(function (a, b) {
result.push(Math.abs(a - b));
return b;
});
console.log(result);

here is a simple solution with a plain old for loop
array = [1, 11, 44, 4]
diff = []
for(var i = 1 ; i < array.length ; i++){
diff.push(Math.abs(array[i] - array[i-1]))
}
basically you loop starting at the second element of the array ,, and subtract from from the prev and pushing to the new array .

use this function, pass it the input array, returns the required array.
function diff(array){
var out = []
for (var i = 0; i < array.length-1; i++) {
out.push(Math.abs(array[i+1]-array[i]))
}
return out;
}

Normally one can do this with .reduce() but just for fun lets get some functional.
var myArray = [1, 11, 44, 4],
diff = a => a.length > 1 ? [Math.abs(a[1]-a[0])].concat(diff(a.slice(1))) : [];
console.log(diff(myArray));
Note: The above code is just for demonstration purposes. In your daily JS life you shouldn't do things like this. Use a whatever loop you like but never use recursion in your JS code. You want to see what i mean? Feed this array.
var myArray = Array(1000000).fill().map(_ => ~~(Math.random()*100+1));
It will beautifully crash your browser's tab. Peah..!

Related

Leetcode Rotate Array works differently in codepen [duplicate]

This question already has answers here:
Rotate the elements in an array in JavaScript
(42 answers)
Closed 2 months ago.
I've solved one of Leetcode problems in codepen, but when I try to submit it on leetcode I get a different result than what I get in codepen.
The problem is:
Given an array, rotate the array to the right by k steps, where k is non-negative.
Example 1:
Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]
Link (requires login) https://leetcode.com/explore/interview/card/top-interview-questions-easy/92/array/646/
My solution:
var rotate = function(nums, k) {
var a = nums.splice(0 , nums.length-k);
var b = nums.splice(-k);
var c = [...b , ...a ];
return(c);
};
Using the above example, running this code on codepen returns (or console.logs) [5,6,7,1,2,3,4].
But when I run this code in leetcode, I get an empty array [].
Any ideas why this could be the happening?
It looks like you're supposed to rotate the original array, not return a new rotated array. So you need to set nums = [...b, ...a] instead.
EDIT: Since JavaScript passes by value, the nums parameter just holds a reference to the original array, so doing nums = [] will only change the nums variable to reference a different array, without changing the original array. You'll want to call methods of the original array to mutate it. E.g. .splice
/EDIT
Also, have you thought about what happens when k is greater than the length of the array? E.g. nums = [1, 2, 3], k = 5
Also also, your link to leetcode requires login, so not everyone will be able to view it.
Example A
.pop() removes the last element of an array and returns it. .unshift() the returned value of .pop() to the first index of the array. Do that k times in a for loop. .pop() and .unshift() changes (aka mutates) the original array.
let arr = [1, 2, 3, 4, 5, 6, 7], k = 3;
function rotate(array, times) {
for (let i=0; i < times; i++) {
let last = array.pop();
array.unshift(last);
}
return array;
}
console.log(rotate(arr, k));
Example B
By changing .splice() to .slice() you can implement your logic since .slice() creates a shallow copy of the array and does not mutate the original array like .splice(). Since the original array is unchanged, any references to said array are consistent. Also, concerning the case mentioned in LawrenceWebDev's answer -- if k is greater than the length of the array -- k (times) becomes the remainder of k/array.length (times % size).
let arr = [1, 2, 3, 4, 5, 6, 7], k = 3;
function rotate(array, times) {
const size = array.length;
if (times > size) {
times = times % size;
}
let a = array.slice(-times);
let b = array.slice(0, size - times);
return [...a, ...b];
}
console.log(rotate(arr, k));

JS: Array print the values that repeat

I need to print the duplicates from an array.
For example, given the following array and index, the function will print 6,23,33,100.
var array = [3,6,67,6,23,11,100,8,93,0,17,24,7,1,33,45,28,33,23,12,99,100];
Apparently we need to do it using two 'while loops'.
Im looking for a solution, but more importantly an explanation.
Links are very much appreciated.
Thanks!
The most elegant and efficient solution is to use a while loop which iterates the array only once, so, we have O(N) complexity.
For this, we need to declare an hash which keeps the number of occurencies for each array's item. If we found a duplicate one then we store it in duplicates array.
var arr = [3,6,67,6,23,11,100,8,93,0,17,24,7,1,33,45,28,33,23,12,99,100], i = 0, hash = {}, duplicates = [];
while(i < arr.length){
hash[arr[i]] = hash[arr[i]] ? hash[arr[i]] += 1 : 1;
if (hash[arr[i]] === 2)
duplicates.push(arr[i])
i++;
}
console.log(duplicates)
You could use the filter() and indexOf() methods.
var array = [3,6,67,6,23,11,100,8,93,0,17,24,7,1,33,45,28,33,23,12,99,100];
console.log(array.filter((a,b,c) => c.indexOf(a) !== b));
a -> is the value being passed in the arrow function.
b -> is the index being passed in.
c -> is the whole array being passed in.
This line is filtering the array based on, if the original array has a value (argument a) whose index does not match the given index passed in through the arrow function (argument b).
A good sample and explanation can be found here... W3Resource
Futhermore to assist in understanding the two major components of the code the Object...
Working with objects - Javascipt
and Arrays...Javascipt Arrays
For the shortest approach, you could take a closure
(s => )( )
with a Set
(s => )(new Set)
and a check. If a value is already seen, then take this value
(s => v => s.has(v) )(new Set)
or add the value to the set and return false, because a not seen value should not in the result set.
(s => v => !s.add(v))(new Set)
var array = [3, 6, 67, 6, 23, 11, 100, 8, 93, 0, 17, 24, 7, 1, 33, 45, 28, 33, 23, 12, 99, 100],
duplicates = array.filter((s => v => s.has(v) || !s.add(v))(new Set));
console.log(duplicates);

Filtering an array and converting it to a 2D array

I saw this interesting post yesterday, and thought it'd be important to know how to create a 2D array from sorting the given argument:
How to get even numbers array to print first instead of odds?
Below is the code snippet from Ori Drori.
I was curious to know what line of code, and which expression sorts the data and creates 2D array. I assume it's something to do with [numbersArray[i] % 2], but isn't the remainder operator returns the remainder left over?
Also it's a bit confusing as it just set one bracket for an array and use push() to make 2 different arrays.
Any reference that'd help me to understand this will also be much appreciated- thanks!
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider(numbersArray) {
var evensOdds = [[], []];
for (var i = 0; i < numbersArray.length; i++) {
evensOdds[numbersArray[i] % 2].push(numbersArray[i]);
}
return evensOdds;
}
console.log(divider(numbersArray));
evensOdds has 2 array elements. evensOdds[0] represents first array, which will hold even nums. evensOdds[1] is second element and will hold odd numbers.
When you % 2 an even number, it will result in 0 and 1 for odd number. So when iterating through the array, you % 2, which will return 0 or 1 which enables you to access the first or second array in your evensOdds array and insert it.
The resulting arrays are not sorted but does represent the split between even and odd numbers. To have a sorted results, you will need the following:
var numbersArray = [1,2,34,54,55,34,32,11,19,17,54,66,13];
function divider(numbersArray) {
var evensOdds = [[], []];
for (var i = 0; i < numbersArray.length; i++) {
evensOdds[numbersArray[i] % 2].push(numbersArray[i]);
}
return evensOdds.map(array=> array.sort((a,b)=>a-b));
}
console.log(divider(numbersArray));
In the shared code the evensOdds[numbersArray[i] % 2] line is the part that filter the numbers and inserts them in the respective array, using the indexes 0 and 1 returned from the numbersArray[i] % 2 expression:
If it returns 0 so it's an even number and it will be pushed in the first array otherwise if it returns 1 it's an odd number and will be pushed in the second array.
Another alternative:
Well you can simply use Array.filter() method to filter both evens and odds arrays:
Demo:
var numbersArray = [1, 2, 34, 54, 55, 34, 32, 11, 19, 17, 54, 66, 13];
var evens = numbersArray.filter(function(el) {
return el % 2 == 0;
});
var odds = numbersArray.filter(function(el) {
return el % 2 == 1;
});
console.log(evens);
console.log(odds);

Duplicate an array an arbitrary number of times (javascript)

Let's say I'm given an array. The length of this array is 3, and has 3 elements:
var array = ['1','2','3'];
Eventually I will need to check if this array is equal to an array with the same elements, but just twice now. My new array is:
var newArray = ['1','2','3','1','2','3'];
I know I can use array.splice() to duplicate an array, but how can I duplicate it an unknown amount of times? Basically what I want is something that would have the effect of
var dupeArray = array*2;
const duplicateArr = (arr, times) =>
Array(times)
.fill([...arr])
.reduce((a, b) => a.concat(b));
This should work. It creates a new array with a size of how many times you want to duplicate it. It fills it with copies of the array. Then it uses reduce to join all the arrays into a single array.
The simplest solution is often the best one:
function replicate(arr, times) {
var al = arr.length,
rl = al*times,
res = new Array(rl);
for (var i=0; i<rl; i++)
res[i] = arr[i % al];
return res;
}
(or use nested loops such as #UsamaNorman).
However, if you want to be clever, you also can repeatedly concat the array to itself:
function replicate(arr, times) {
for (var parts = []; times > 0; times >>= 1) {
if (times & 1)
parts.push(arr);
arr = arr.concat(arr);
}
return Array.prototype.concat.apply([], parts);
}
Basic but worked for me.
var num = 2;
while(num>0){
array = array.concat(array);
num--}
Here's a fairly concise, non-recursive way of replicating an array an arbitrary number of times:
function replicateArray(array, n) {
// Create an array of size "n" with undefined values
var arrays = Array.apply(null, new Array(n));
// Replace each "undefined" with our array, resulting in an array of n copies of our array
arrays = arrays.map(function() { return array });
// Flatten our array of arrays
return [].concat.apply([], arrays);
}
console.log(replicateArray([1,2,3],4)); // output: [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
What's going on?
The first two lines use apply and map to create an array of "n" copies of your array.
The last line uses apply to flatten our recently generated array of arrays.
Seriously though, what's going on?
If you haven't used apply or map, the code might be confusing.
The first piece of magic sauce here is the use of apply() which makes it possible to either pass an array to a function as though it were a parameter list.
Apply uses three pieces of information: x.apply(y,z)
x is the function being called
y is the object that the function is being called on (if null, it uses global)
z is the parameter list
Put in terms of code, it translates to: y.x(z[0], z[1], z[2],...)
For example
var arrays = Array.apply(null, new Array(n));
is the same as writing
var arrays = Array(undefined,undefined,undefined,... /*Repeat N Times*/);
The second piece of magic is the use of map() which calls a function for each element of an array and creates a list of return values.
This uses two pieces of information: x.map(y)
x is an array
y is a function to be invoked on each element of the array
For example
var returnArray = [1,2,3].map(function(x) {return x + 1;});
would create the array [2,3,4]
In our case we passed in a function which always returns a static value (the array we want to duplicate) which means the result of this map is a list of n copies of our array.
You can do:
var array = ['1','2','3'];
function nplicate(times, array){
//Times = 2, then concat 1 time to duplicate. Times = 3, then concat 2 times for duplicate. Etc.
times = times -1;
var result = array;
while(times > 0){
result = result.concat(array);
times--;
}
return result;
}
console.log(nplicate(2,array));
You concat the same array n times.
Use concat function and some logic: http://www.w3schools.com/jsref/jsref_concat_array.asp
Keep it short and sweet
function repeat(a, n, r) {
return !n ? r : repeat(a, --n, (r||[]).concat(a));
}
console.log(repeat([1,2,3], 4)); // [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
http://jsfiddle.net/fLo3uubk/
if you are inside a loop you can verify the current loop index with the array length and then multiply it's content.
let arr = [1, 2, 3];
if(currentIndex > arr.length){
//if your using a loop, make sure to keep arr at a level that it won't reset each loop
arr.push(...arr);
}
Full Example:
https://jsfiddle.net/5k28yq0L/
I think you will have to write your own function, try this:
function dupArray(var n,var arr){
var newArr=[];
for(var j=0;j<n;j++)
for(var i=0;i<arr.length;i++){
newArr.push(arr[i]);
}
return newArr;
}
A rather crude solution for checking that it duplicates...
You could check for a variation of the length using modulus:
Then if it might be, loop over the contents and compare each value until done. If at any point it doesn't match before ending, then it either didn't repeat or stopped repeating before the end.
if (array2.length % array1.length == 0){
// It might be a dupe
for (var i in array2){
if (i != array1[array2.length % indexOf(i)]) { // Not Repeating }
}
}

How to initialize an array's length in JavaScript?

Most of the tutorials that I've read on arrays in JavaScript (including w3schools and devguru) suggest that you can initialize an array with a certain length by passing an integer to the Array constructor using the var test = new Array(4); syntax.
After using this syntax liberally in my js files, I ran one of the files through jsLint, and it freaked out:
Error: Problem at line 1 character 22: Expected ')' and instead saw '4'.
var test = new Array(4);
Problem at line 1 character 23: Expected ';' and instead saw ')'.
var test = new Array(4);
Problem at line 1 character 23: Expected an identifier and instead saw ')'.
After reading through jsLint's explanation of its behavior, it looks like jsLint doesn't really like the new Array() syntax, and instead prefers [] when declaring arrays.
So I have a couple questions:
First, why? Am I running any risk by using the new Array() syntax instead? Are there browser incompatibilities that I should be aware of?
And second, if I switch to the square bracket syntax, is there any way to declare an array and set its length all on one line, or do I have to do something like this:
var test = [];
test.length = 4;
Array(5) gives you an array with length 5 but no values, hence you can't iterate over it.
Array.apply(null, Array(5)).map(function () {}) gives you an array with length 5 and undefined as values, now it can be iterated over.
Array.apply(null, Array(5)).map(function (x, i) { return i; }) gives you an array with length 5 and values 0,1,2,3,4.
Array(5).forEach(alert) does nothing, Array.apply(null, Array(5)).forEach(alert) gives you 5 alerts
ES6 gives us Array.from so now you can also use Array.from(Array(5)).forEach(alert)
If you want to initialize with a certain value, these are good to knows...
Array.from('abcde'), Array.from('x'.repeat(5))
or Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]
With ES2015 .fill() you can now simply do:
// `n` is the size you want to initialize your array
// `0` is what the array will be filled with (can be any other value)
Array(n).fill(0)
Which is a lot more concise than Array.apply(0, new Array(n)).map(i => value)
It is possible to drop the 0 in .fill() and run without arguments, which will fill the array with undefined. (However, this will fail in Typescript)
Why do you want to initialize the length? Theoretically there is no need for this. It can even result in confusing behavior, because all tests that use the length to find out whether an array is empty or not will report that the array is not empty.
Some tests show that setting the initial length of large arrays can be more efficient if the array is filled afterwards, but the performance gain (if any) seem to differ from browser to browser.
jsLint does not like new Array() because the constructer is ambiguous.
new Array(4);
creates an empty array of length 4. But
new Array('4');
creates an array containing the value '4'.
Regarding your comment: In JS you don't need to initialize the length of the array. It grows dynamically. You can just store the length in some variable, e.g.
var data = [];
var length = 5; // user defined length
for(var i = 0; i < length; i++) {
data.push(createSomeObject());
}
[...Array(6)].map(x => 0);
// [0, 0, 0, 0, 0, 0]
OR
Array(6).fill(0);
// [0, 0, 0, 0, 0, 0]
Note: you can't loop empty slots i.e. Array(4).forEach(() => …)
OR
( typescript safe )
Array(6).fill(null).map((_, i) => i);
// [0, 1, 2, 3, 4, 5]
OR
Classic method using a function ( works in any browser )
function NewArray(size) {
var x = [];
for (var i = 0; i < size; ++i) {
x[i] = i;
}
return x;
}
var a = NewArray(10);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Creating nested arrays
When creating a 2D array with the fill intuitively should create new instances. But what actually going to happen is the same array will be stored as a reference.
var a = Array(3).fill([6]);
// [ [6], [6], [6] ]
a[0].push(9);
// [ [6, 9], [6, 9], [6, 9] ]
Solution
var a = [...Array(3)].map(x => []);
a[0].push(4, 2);
// [ [4, 2], [], [] ]
So a 3x2 Array will look something like this:
[...Array(3)].map(x => Array(2).fill(0));
// [ [0, 0], [0, 0], [0, 0] ]
N-dimensional array
function NArray(...dimensions) {
var index = 0;
function NArrayRec(dims) {
var first = dims[0], next = dims.slice().splice(1);
if(dims.length > 1)
return Array(dims[0]).fill(null).map((x, i) => NArrayRec(next ));
return Array(dims[0]).fill(null).map((x, i) => (index++));
}
return NArrayRec(dimensions);
}
var arr = NArray(3, 2, 4);
// [ [ [ 0, 1, 2, 3 ] , [ 4, 5, 6, 7] ],
// [ [ 8, 9, 10, 11] , [ 12, 13, 14, 15] ],
// [ [ 16, 17, 18, 19] , [ 20, 21, 22, 23] ] ]
Initialize a chessboard
var Chessboard = [...Array(8)].map((x, j) => {
return Array(8).fill(null).map((y, i) => {
return `${String.fromCharCode(65 + i)}${8 - j}`;
});
});
// [ [A8, B8, C8, D8, E8, F8, G8, H8],
// [A7, B7, C7, D7, E7, F7, G7, H7],
// [A6, B6, C6, D6, E6, F6, G6, H6],
// [A5, B5, C5, D5, E5, F5, G5, H5],
// [A4, B4, C4, D4, E4, F4, G4, H4],
// [A3, B3, C3, D3, E3, F3, G3, H3],
// [A2, B2, C2, D2, E2, F2, G2, H2],
// [A1, B1, C1, D1, E1, F1, G1, H1] ]
Math filled values
handy little method overload when working with math
function NewArray( size , method, linear )
{
method = method || ( i => i );
linear = linear || false;
var x = [];
for( var i = 0; i < size; ++i )
x[ i ] = method( linear ? i / (size-1) : i );
return x;
}
NewArray( 4 );
// [ 0, 1, 2, 3 ]
NewArray( 4, Math.sin );
// [ 0, 0.841, 0.909, 0.141 ]
NewArray( 4, Math.sin, true );
// [ 0, 0.327, 0.618, 0.841 ]
var pow2 = ( x ) => x * x;
NewArray( 4, pow2 );
// [ 0, 1, 4, 9 ]
NewArray( 4, pow2, true );
// [ 0, 0.111, 0.444, 1 ]
The shortest:
let arr = [...Array(10)];
console.log(arr);
ES6 introduces Array.from which lets you create an Array from any "array-like" or iterables objects:
Array.from({length: 10}, (x, i) => i);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In this case {length: 10} represents the minimal definition of an "array-like" object: an empty object with just a length property defined.
Array.from allows for a second argument to map over the resulting array.
Sparse arrays are here! 🥳 [2021]
In modern JS engines, sparse arrays are fully supported. You can use [] or new Array(len) in any way you like, even with random access. Dictionary mode seems to be a thing of the past.
In current Chrome (and I guess any V8 environment), Arrays can have a length of up to 2^32-1 and allocation is sparse (meaning empty chunks don't use up any memory):
However, there is a catch
On the one hand, for loops work as intended, however, Array's builtin higher order functions (such as map, filter, find, some etc.) ignore unassigned elements. They require fill (or some other method of population) first:
const a = new Array(10);
const b = new Array(10).fill(0);
a.forEach(x => console.log(x)); // does nothing
b.forEach(x => console.log(x)); // works as intended
Old Version
(I removed most of the old version.) The gist was that creating a large array using new Array(largeNumber) or random accessing an array in places that have not yet been allocated would tumble it into "dictionary mode". Meaning you are using an array with indexes, but under the hood it would use a dictionary to store the values, thus messing with performance, and also with iteration behavior. Luckily that is a thing of the past.
This will initialize the length property to 4:
var x = [,,,,];
I'm surprised there hasn't been a functional solution suggested that allows you to set the length in one line. The following is based on UnderscoreJS:
var test = _.map(_.range(4), function () { return undefined; });
console.log(test.length);
For reasons mentioned above, I'd avoid doing this unless I wanted to initialize the array to a specific value. It's interesting to note there are other libraries that implement range including Lo-dash and Lazy, which may have different performance characteristics.
Here is another solution
var arr = Array.apply( null, { length: 4 } );
arr; // [undefined, undefined, undefined, undefined] (in Chrome)
arr.length; // 4
The first argument of apply() is a this object binding, which we don't care about here, so we set it to null.
Array.apply(..) is calling the Array(..) function and spreading out the { length: 3 } object value as its arguments.
Please people don't give up your old habits just yet.
There is a large difference in speed between allocating memory once then working with the entries in that array (as of old), and allocating it many times as an array grows (which is inevitably what the system does under the hood with other suggested methods).
None of this matters of course, until you want to do something cool with larger arrays. Then it does.
Seeing as there still seems to be no option in JS at the moment to set the initial capacity of an array, I use the following...
var newArrayWithSize = function(size) {
this.standard = this.standard||[];
for (var add = size-this.standard.length; add>0; add--) {
this.standard.push(undefined);// or whatever
}
return this.standard.slice(0,size);
}
There are tradeoffs involved:
This method takes as long as the others for the first call to the function, but very little time for later calls (unless asking for a bigger array).
The standard array does permanently reserve as much space as the largest array you have asked for.
But if it fits with what you're doing there can be a payoff.
Informal timing puts
for (var n=10000;n>0;n--) {var b = newArrayWithSize(10000);b[0]=0;}
at pretty speedy (about 50ms for the 10000 given that with n=1000000 it took about 5 seconds), and
for (var n=10000;n>0;n--) {
var b = [];for (var add=10000;add>0;add--) {
b.push(undefined);
}
}
at well over a minute (about 90 sec for the 10000 on the same chrome console, or about 2000 times slower).
That won't just be the allocation, but also the 10000 pushes, for loop, etc..
(this was probably better as a comment, but got too long)
So, after reading this I was curious if pre-allocating was actually faster, because in theory it should be. However, this blog gave some tips advising against it http://www.html5rocks.com/en/tutorials/speed/v8/.
So still being unsure, I put it to the test. And as it turns out it seems to in fact be slower.
var time = Date.now();
var temp = [];
for(var i=0;i<100000;i++){
temp[i]=i;
}
console.log(Date.now()-time);
var time = Date.now();
var temp2 = new Array(100000);
for(var i=0;i<100000;i++){
temp2[i] = i;
}
console.log(Date.now()-time);
This code yields the following after a few casual runs:
$ node main.js
9
16
$ node main.js
8
14
$ node main.js
7
20
$ node main.js
9
14
$ node main.js
9
19
var arr=[];
arr[5]=0;
alert("length="+arr.length); // gives 6
The simplest form is to use
Array.from({ length: 3 });
// gives you
[undefined, undefined, undefined]
Unlike Array(3) which will give you an array you can't iterate over. Array.from({ length }) gives you an array you can iterate easily.
Array.from({ length: 3 }).map((e, idx) => `hi ${idx}`);
// ['hi 1', 'hi 2', 'hi 3']
Assuming that Array's length is constant. In Javascript, This is what we do:
const intialArray = new Array(specify the value);
The array constructor has an ambiguous syntax, and JSLint just hurts your feelings after all.
Also, your example code is broken, the second var statement will raise a SyntaxError. You're setting the property length of the array test, so there's no need for another var.
As far as your options go, array.length is the only "clean" one. Question is, why do you need to set the size in the first place? Try to refactor your code to get rid of that dependency.
In addition to the answers of others, another clever way is to use Float32Array to create an array and iterate on it.
For this purpose, create an instance from Float32Array with your desired length like this:
new Float32Array(5)
This code returns an array-like that you can convert it to an array with Array.from():
Array.from(new Float32Array(5)) // [0, 0, 0, 0, 0]
You can also use fill() to change the value of items:
Array.from(new Float32Array(5).fill(2)) // [2, 2, 2, 2, 2]
And of course you can iterate on it:
Array.from(new Float32Array(5)).map(item => /* ... */ )
In most answers it is recommended to fill the array because otherwise "you can't iterate over it", but this is not true. You can iterate an empty array, just not with forEach. While loops, for of loops and for i loops work fine.
const count = Array(5);
Does not work.
console.log('---for each loop:---');
count.forEach((empty, index) => {
console.log(`counting ${index}`);
});
These work:
console.log('---for of loop:---');
for (let [index, empty] of count.entries()) {
console.log(`counting for of loop ${index}`);
}
console.log('---for i loop:---');
for (let i = 0, il = count.length; i < il; ++i) {
console.log(`counting for i loop ${i}`);
}
console.log('---while loop:---');
let index = 0;
while (index < count.length) {
console.log(`counting while loop ${index}`);
index++;
}
Check this fiddle with the above examples.
Also angulars *ngFor works fine with an empty array:
<li *ngFor="let empty of count; let i = index" [ngClass]="
<span>Counting with *ngFor {{i}}</span>
</li>
You can set the array length by using array.length = youValue
So it would be
var myArray = [];
myArray.length = yourValue;
The reason you shouldn't use new Array is demonstrated by this code:
var Array = function () {};
var x = new Array(4);
alert(x.length); // undefined...
Some other code could mess with the Array variable. I know it's a bit far fetched that anyone would write such code, but still...
Also, as Felix King said, the interface is a little inconsistent, and could lead to some very difficult-to-track-down bugs.
If you wanted an array with length = x, filled with undefined (as new Array(x) would do), you could do this:
var x = 4;
var myArray = [];
myArray[x - 1] = undefined;
alert(myArray.length); // 4

Categories

Resources