0

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 } ]);
}
7
  • The task can be done by a for-loop, Commented May 31, 2021 at 6:19
  • 4
    return this.result = Array.from({ length: Math.floor(this.foo) }, (_, index) => ({ year: index + 1 }));? Familiarize yourself with how to access and process objects and arrays and how to create objects and use the available Object and Array methods (both static and on prototype). Commented May 31, 2021 at 6:19
  • 1
    It would be better if you described your question. For example "I want to produce an array of length this.foo - 1 filled with objects of {year: n} where n is the 1-based index of the object in the array". Sound about right? Commented May 31, 2021 at 6:20
  • @Phil thank you for your specific comments!! My English is not good so it is little difficult to specify what I want TT Commented May 31, 2021 at 6:23
  • 1
    Related: How to create an array containing 1…N. Commented May 31, 2021 at 6:24

4 Answers 4

7

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));

Sign up to request clarification or add additional context in comments.

Comments

4

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;

5 Comments

Shouldn't it be Math.max(1, ...?
@Phil Depends on the exact requirements. I’ve included a paragraph that explains this.
@SebastianSimon Thanks, I am writing the codes myself and learning them!!!
@SebastianSimon It doesn't look like Array(n) takes space n immediately. Shoudn't it be two steps?
@zmag You’re kind of right: Array(n) creates a new array, nonetheless, but I forgot that .fill mutates the array instead of creating a new array.
2

try this oneliner

let x=3;
let result = [ ...Array(x).keys() ].map(item=> {return{"year":item}});
console.log(result);

Comments

1
let arr = [];

for(let i = 1; i<this.foo;i++){ 
    arr.push({ 'year':i}) 
};

console.log(arr);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.