Reputation: 71
I want to improve my ugly code to something more clean and simple. How can I shorten this code?
if (this.foo < 2) {
return (this.result = [ { year: 1 } ]);
}
if (this.foo < 3) {
return (this.result = [ { year: 1 }, { year: 2 } ]);
}
if (this.foo < 4) {
return (this.result = [ { year: 1 }, { year: 2 }, { year: 3 } ]);
}
if (this.foo < 5) {
return (this.result = [ { year: 1 }, { year: 2 }, { year: 3 }, { year: 4 } ]);
}
if (this.foo < 6) {
return (this.result = [ { year: 1 }, { year: 2 }, { year: 3 }, { year: 4 }, { year: 5 } ]);
}
Upvotes: 0
Views: 1042
Reputation: 19475
What you’ve shown is equivalent to this (except this goes beyond five elements, but also beyond one in the other direction):
return this.result = Array.from({
length: Math.floor(this.foo)
}, (_value, index) => ({
year: index + 1
}));
This assumes that this statement is inside a function (otherwise, return
wouldn’t work).
A more reasonable length may be Math.max(0, Math.min(2 ** 32 - 1, Math.floor(this.foo)))
which clamps1 the length to at least 0 and at most 232 − 1, the maximum Array length.
If you want to always have at least one element in your array, then use Math.max(1,
…)
instead.
Returning an assignment (i.e. return this.result =
…;
) is frowned upon.
The best practice is to separate these statements2:
this.result = Array.from({
length: Math.max(0, Math.min(2 ** 32 - 1, Math.floor(this.foo)))
}, (_value, index) => ({
year: index + 1
}));
return this.result;
Array.from
is used with both arguments: the first one is the “array-like” object { length: Math.max(0, Math.min(2 ** 32 - 1, Math.floor(this.foo))) }
which gets converted to a proper Array
object.
In this case, an array with a length of Math.floor(this.foo)
is initialized (clamped to the range of possible Array lengths).
The second argument maps each value at a certain index
to an object with the year
property with the value index + 1
.
_value
isn’t used (it’s undefined
anyway).
The advantage to use Array.from(
array-like,
mapping-function)
over e.g. .fill().map(
…)
is that only a single array is created in memory.
Array(
…).fill().map(
…)
creates two new arrays: the first one at Array(
…).fill()
, the second one at .map(
…)
.
Therefore, the Array.from
approach is more memory-efficient.
1: Maybe soon we’ll finally get a Math.clamp
method…
2: Technically, this would be equivalent.
If this.result
is a getter / setter, there may be an observable difference.
const result = Array.from({
length: Math.max(0, Math.min(2 ** 32 - 1, Math.floor(this.foo)))
}, (_value, index) => ({
year: index + 1
}));
this.result = result;
return result;
Upvotes: 4
Reputation: 1053
try this oneliner
let x=3;
let result = [ ...Array(x).keys() ].map(item=> {return{"year":item}});
console.log(result);
Upvotes: 2
Reputation: 8241
Create an array with Array
, and use Array.prototype.map
.
function func(foo) {
return Array(foo).fill().map((f, i) => ({ year: i + 1 }));
}
console.log(func(1));
console.log(func(3));
Upvotes: 7
Reputation: 3910
let arr = [];
for(let i = 1; i<this.foo;i++){
arr.push({ 'year':i})
};
console.log(arr);
Upvotes: 1