简体   繁体   中英

Possible to push empty slot to an array?

I'm building my own map method to be as close as the native map method. Since the native map pushes(i think) the changed values into a new array, it still keeps the empty slots. I wasn't able to find a solution to push an empty slot into an array, like this example below.

[1, 2, 3].push(some code) // [1, 2, 3, empty]

I tried pushing an array with one empty item prefixed with a spread operator arr.push(...(new Array(1))) or arr.push(...[,]) but that just pushes undefined .

I solved my problem by not using push and instead assigning values to the array index that way skipped indices will be set to empty.

But I'm writing this post to see if anyone knows that if it's possible to use the push method to push an empty slot to an array.

No, it's not possible, not with the push method. empty can only exist if the array has a certain length, but a whole number property of the array does not exist at some index. This is called a sparse array , and cannot be created with push (or other array methods, if they're called on and with non-sparse arrays).

The only way to do so would be to assign to an index for which a lower index doesn't exist yet.

Look at the results for the below two snippets in your browser console, not the snippet console:

 const arr = []; arr[1] = 'a'; console.log(arr); 

Or to set the .length of the array above the last index that the array has:

 const arr = []; arr.length = 1; console.log(arr); 

But the two approaches above are very weird to do and probably have no good reason to be used. Better to avoid sparse arrays entirely.

Keep in mind that an empty slot is different from undefined , which is perfectly possible to have as an array value:

 const arr = []; arr.push(undefined); console.log(arr); 

You can create an empty slot in an array by incrementing the array length:

 var a = [] a.push(1) a.length++ a.push(3) console.log(a) console.log(1 in a) // anything at index 1? 

Alternatively, you can push something and then delete it:

 var a = [] a.push(1) a.push(2) a.push(3) delete a[1] console.log(a) console.log(1 in a) // anything at index 1? 

There is no need to actually push to a new array in your implementation. You can simply do new Array(this.length) where this.length is the array you are mapping through length.

For example consider this map implementation:

 if (!Array.prototype.mapIt) { Object.defineProperty(Array.prototype, "mapIt", { value: function(fn) { if (this === null) { throw new TypeError('Array.prototype.mapIt called on null or undefined'); } if (typeof fn !== 'function') { throw new TypeError('predicate must be a function'); } let _array = this.filter(x => x != null) // remove empty values let result = new Array(_array.length) // the new array we will return for (var i = 0; i < _array.length; i++) { result[i] = fn.call(arguments[1], _array[i], i, _array) // call the predicate } return result; } }); } let arr = [1, 2, , , 3] // the test array let result = arr.mapIt((c, i, a) => console.log(`current: ${c}`, `index: ${i}`, `array: ${a}`) || c + 2) console.log('result: ', result) console.log('original array: ', arr) 

Hope this helps you with an gives you an idea about a possible map implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM