Have any of you found cool ways of generating arrays in js. I don't have to do this very often, but this is the best way I've found to do it.
const firstTenSqaures = Array.from(Array(10), (_, i) => i ** 2)
Have any of you found cool ways of generating arrays in js. I don't have to do this very often, but this is the best way I've found to do it.
const firstTenSqaures = Array.from(Array(10), (_, i) => i ** 2)
I’d suggest avoiding the Array constructor entirely - use { length: 10 }
instead of Array(10).
Yeah, I know you can do that { length: 10 }
, but that kind of looks like magic. Why should the Array constructor be avoided?
Because it creates a sparse array.
Right. I didn't think that would really matter here. What about?
const tenTens = new Array(10).fill(10)
I'm not sure what qualifies as cool but generators provide a lot of fun!
Array.from((function*() {
for (let i = 0; i < 10; i++) yield i ** 2;
})()); // [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
There's also a range proposal: Iterator.range()
That would also be good. I feel like the question could also be phrased, what's the least ugly way to do this in js
Please refer to the active thread:
That just returns [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
. If you're looking for a range, Array.prototype.fill
is probably not what you're looking for.
Now if only we could get implementors to optimize it correctly.
I usually do something like:
const myRange = [...new Array(33)]
.map((item, index) => index + 10);
But we really need a standard range functionality
Right, I was just pointing this out as maybe an acceptable case to use the array constructor.
That's kind of esoteric knowledge that {length: n}
works as an array under the hood, imo. Or is an "arrayLike" I guess.
The problem of unintuitive code in generating arrays in JavaScript can be solved as follows:
/* x is used as a variable below in order to bring in a sense of multiplication by some value to give
* an array, in this case, as a result
*/
const x = Symbol ? Symbol() : '1bda4e5b-9819-49f0-bcb3-946697b3b663';
//Symbol() does not return a string as its unique id
//x is defined on the Number.prototype object as a getter
Object.defineProperty(Number.prototype, x, {
get() {
/* this.valueOf below return the number that is currently accessing x as a property
*/
let arg=[], n=this.valueOf(), i=0;
for(; i++<n; arg[i-1]=i-1); return arg;
},
});
/*syntaxes such as 5.x, 10.x won't work because the JavaScript compiler cannot be sure whether
* the dot is for a floating point number or for object property accession.
* it is safe to use syntaxes such as 5[x], 10[x]
*/
5[x] // [0, 1, 2, 3, 4]
200[x] // [0, 1, ..., 199]
Hopefully this helps someone, I look forward to corrections and code improvements
syntaxes such as 5.x, 10.x won't work because the JavaScript compiler cannot be sure whether the dot is for a floating point number or for object property accession.
To solve the syntax issue, you can write 5..x
, but the real issue is that this accesses the property called x
instead of using the expression x
.
Also, speaking of modifying prototypes, maybe someone would enjoy a proxy treat:
Object.setPrototypeOf(
Number.prototype,
new Proxy(Object.prototype, {
get(t, p, r) {
if (typeof p === "string") {
const np = Number(p);
if (Number.isFinite(np)) {
const n = Number(r);
return (function* () {
if (n < np) {
for (let i = n; i < np; i++) {
yield i;
}
} else {
for (let i = n; i > np; i--) {
yield i;
}
}
})();
}
}
return Reflect.get(t, p, r);
},
})
);
console.log([...10[-3]]);
console.log([...0[5]]);
That’s cool. 5..x
looks like a range, but it’s backwards in this case. 0..5
Unfortunately 0..5
is not valid syntax. But I'm trying to think of some other way like 1..x=100
1..to10
, 1..to(10)
, and 1..to[10]
are all possible designs. The issue is that they all create string properties which could harm forward compatibility. Number properties are less dangerous in this regard.
[...0[5]]
I think that's the closest thing to operator-overloading in JS. I'm not sure if I should feel amazed or horrified, haha (No offense intended! That code is actually a very interesting proof-of-concept. I like it )
What's this supposed to do, I put this into the terminal and it spat out caught TypeError: 0[5] is not iterable
All these are pretty gross honestly, maybe just a range function would be the way to go range(0, 5)
Without installing any npm dependencies, I'm pretty happy with
const firstTenSqaures = Array.from({ length: 10 }, (_, i) => i ** 2)
The times I actually need ranges in js is pretty seldom, but still an interesting topic.
@seekr3 Did you run the previous line, which basically hijacks Number.prototype
?