When I do
const arrayLike = { 1:'foo', 2:'bar', length:2 };
Array.from(arrayLike);
I get
[ undefined, 'foo' ]
When I do
const arrayLike = { 1:'foo', 2:'bar', length:3 };
Array.from(arrayLike)
I get
[ undefined, 'foo', 'bar' ]
bar when I set the length?undefined?0 indexed in JavaScriptAll of these questions are answered pretty simply. Array.from assumes that the array-like object you're giving it is zero-indexed. If it isn't you'll get an array that is zero-indexed with all elements that aren't set, including 0 set to undefined. So in your example,
const arrayLike = { 1:'foo', 2:'bar', length:2 };
Array.from(arrayLike);
Is essentially the same as,
const arrayLike = { 0:undefined, 1:'foo', 2:'bar', length:2 };
Array.from(arrayLike);
Because the length is less than the max elements, it essentially stops iterating at that point and the false-length functions as a truncation. What you want is likely,
const arrayLike = { 0:'foo', 1:'bar', length:2 };
Array.from(arrayLike);
Or if you're getting the Array-like from a source that is 1-indexed, set length appropriately so as not to lose the last element, and then ditch the first element from the result (the equivalent of shift).
const arrayLike = { 1:'foo', 2:'bar', length:3 };
let arr = Array.from(arrayLike).splice(1);
let arr = Array.from(arrayLike);
arr.shift();
let [, ...arr] = Array.from(arrayLike);
Array.from(obj) does not return undefined, it returns a new array using properties from a given array-like object obj.
And the default values of each index position created is undefined when not given.
The undefined value you are seeing is at index 0 of the created array.
Anyways, it is not a problem, you can still access the indexes 1 and 2 and they will return the values you expect them to return.
You can also verify the default behavior of created arrays with:
console.log(new Array(10))
which logs (index positions 0..9) (length 10):
[undefined x 10]
In JavaScript, you will not see any array with the first index other than 0. Independently how the array was created.
Another alternative to what you are doing is to set the prototype:
const arrayLike = { 1:'foo', 7:'bar' };
//Dynamic set the length
arrayLike.length = Math.max(...Object.keys(arrayLike)) + 1;
//Get built-in features of Array to your arrayLike
Object.setPrototypeOf(arrayLike, Array.prototype);
//Do something
arrayLike.forEach((x, i) => console.log("%i: %s", i, x))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With