Prefill an Array Exercise

Note: The following post was for a previous iteration of this blog, called Code and Tacos. That version of the blog is dead, but I'm keeping this post up for posterity's sake.

Well it's almost the end of the year, and so much has happened! I'll get to the Codewars solution in a little bit but first I'd like to reflect on 2019.

I started the year out by setting an aggressive number of goals. Here are my 2019 new years resolutions:

1. Dry January: We drink a lot, and I wanted to push my self-control to see how life might look completely sober, so we both did Dry January. It went a lot better than I thought it would. After the first couple of days I didn't really miss booze, and we wound up drinking tea instead. It really felt great. I thought I'd have seen more weight loss or clearer skin, but maybe one month just isn't long enough to see those sorts of changes. I also wound up doing Dry July as well, and it also felt good and clarifying. I think I'll repeat in 2020.

2. Bring my lunch to work 200 times: I'm pretty well on track with this one. I think by my count I'm going to land around 197 or 198. I didn't feel like I was buying my lunch whole lot in 2018, but now that I'm on this roll I can't believe how much money I've saved. A really cool side effect of this goal is that, since I'm doing more dinner cooking with the goal of bringing leftovers the next day I've really noticed an improvement in my cooking skills. I'm just way more confident in the kitchen, and the meals I can produce just keep getting better and better. With that, and the money I've saved, I'm not mad if I'm just a couple of meals off from 200.

3. Finish Code and Tacos: I launched this website in May of 2018 with the goal of setting up an entire tech stack myself, tackling hosting, DNS, name records, and a CMS. My objective was to keep the site up and to do 20 blog posts: 10 about coding and 10 that were taco recipes. Hence the name, Code and Tacos. By the time 2019 rolled around, I was probably about halfway through those posts, but I just kept getting distracted -- life or work or whatever, I just couldn't find the time to write. So I made a resolution to finish those 20 blog posts and see how I was feeling afterward. I've really taken off on the coding stuff, doing a huge series on array methods, and I feel like the more I blog about coding, the better I get as a programmer. The taco posts are still there, and I'll keep up with food blogging, but I'm no food photographer, and it's pretty unmotivating to have an ugly food blog. Still, I love the name of the blog. I'm going to keep it going, since it doesn't cost me a whole lot and I learn a lot even just running the blog.

4. Kill it at my Tech Con Presentation: Done.

5. Run a 5k: Not exactly done. I signed up for the Cap 10k, then that got canceled because of rain. Then I signed up for the Longhorn Run 10k a week later. They shut the race down when I was almost halfway through the course because of lightning, so I got to like 4.5k in that race. Then a few weeks later I signed up for and ran the Sunshine Run 10k in gorgeous weather. The playlist for that race is here. Just a couple of weeks ago I also ran the Turkey Trot, which is 5 miles long. The playlist for that race is here. So while I didn't run a 5k specifically, I have run longer races and put myself in the habit of running.

6. Visit another country: We went to Vancouver, Canada in September! It was awesome.

7. Finish Eloquent JavaScript: Not done. I got about halfway through, and I just couldn't do it. That class-style programming just isn't exactly what I do anyway. I did read all of Kyle Simpson's You Don't Know JS series though.

8. Read 14 books: Not done. I might be able to finish it but I'm not really rushing myself. I think I'm about halfway through my 12th book this year.

9. Save 19% of my income: Hahahahahahaha. Nope, not done. I think I've managed to put away about 12% though, which feels great! I managed that through my whole bringing lunch to work thing I talked about earlier.

10. Do 26 Codewar challenges: Not done, I think I've done three this year. I do want to keep training up though, since it's really a good way to practice my coding skills. With that said, let me finally get to the Codewars Kata this blog post promises.

Today's Kata comes from user5854572 and is titled Prefill an Array.

Prompt: Prefill an Array

Create the function prefill that returns an array of n elements that all have the same value v. See if you can do this without using a loop.

You have to validate input:

  • v can be anything (primitive or otherwise)
  • if v is ommited, fill the array with undefined
  • if n is 0, return an empty array
  • if n is anything other than an integer or integer-formatted string (e.g. '123') that is >=0, throw a TypeError
  • When throwing a TypeError, the message should be n is invalid, where you replace n for the actual value passed to the function.

Solution: Prefill an Array

For this one, the biggest hurdle is the amount of validation that needs to be passed. To make sure n isn't NaN, I run it through isNaN (parseInt(n)). I use the modulus operator to ensure it's not a float (n % 1 !== 0), and also make sure that it isn't a negative number. In any of those cases hit then I'll just throw the error. It's easy enough to make sure we replace n with the actual value passed by using an ES6 template literal.

If it passes all of the above conditions, it's just a simple matter of building up the array. This can be done a number of ways, but I decided to go with Array.from(). You may recall from this blog post on the Array.from() method that you can easily construct an array of any length by passing it an object with a length property. In the following case it just makes an Array with n number of items. Those items are undefined, so it's then just a matter of running .fill(v) to fill the array with the v value.

function prefill(n, v) {
  if (isNaN(parseInt(n)) || n % 1 !== 0 || n < 0) {
    throw new TypeError(`${n} is invalid`);
  }
  return Array.from({ length: n }).fill(v);
};