Category: tips

Spread and Exclude

Spread and Exclude

The other day I wanted to log out some values of a large object. But one particular property was massive and not needed. So how could I pass all of the original object minus that one property that was going to get in the way?
As in how to exclude a single property from a object.


It’s a very simple and I think elegant solution. so here it is.

Using the spread operator you can list the specific items to copy first (these will then be excluded) then use the … rest operator to copy the remaining items.

That’s it! It telling your code what to specifically copy first, those will then not be included when you use the rest operator. Brilliant!

const bigObject = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6};
const { a, ...copiedAndExcluded } = bigObject;
// copiedAndExcluded is now the same as bigObject, expect it doesn't have the property 'a'.

Also in my case the bigObject was a property of something else, which at times may have been undefined. This will cause an error, as you can’t spread undefined.

const parentObject = { a: 1, bigObject = undefined, c: 3, d: 4};
const { a, ...copiedAndExcluded } = parentObject.bigObject || {};
// 'a' and 'copiedAndExcluded' will be undefined

The `|| {}` will make sure that the code doesn’t try to spread the value of undefined (as that will throw an error). You can however spread an empty object. The values that come out will be undefined, which in my case was just fine.

Cycles of Life – A Cautionary Tale!

Cycles of Life – A Cautionary Tale!

β€œThose who do not learn from history are doomed to repeat it.” (George Santayana)

Having been around the software world for more than a few years you see the same cycles time and again. That rather old phrase of “those who do not learn from history are doomed to repeat it.” comes to mind.
Teams grow and shrink and all going well grow again, prepare for it, so you can mange it.

More appropriately this should be called –
Cycles of Life a Software Team – A Cautionary Tale!

Software and the teams around them are on the whole very versatile and nothing is really doomed. It will probably just slow (hugely) you down or cost someone a shed load of cash to sort out πŸ˜›

We’re entering a new year, all going well your team is looking forward to growing, so keep the following in mind!
When you know what to look for then hopefully you can do something about it.

Team growth

  • How big is your overall team?
  • How big are the individual teams within the overall team?
  • How quickly has the team grown?
  • How quickly do you want it to grow?

These questions are key to figure out what will happen. The following has happened on more than one occasion and in completely different teams.

How quickly have you grown?

You are an awesome start up, your idea is a massive hit with the investors, it’s time to grow, grow, grow!

Here’s the thing, the software industry has a HUGE staff churn rate. Even the best companies will struggle to keep staff for a long time. You must be prepared for this.

Your team has grown from 10 to 30, maybe even 50+ in a very short period. The buzz around you encourages others to join. Nothing better than a greenfield project to work on.

Here’s the rub, all those new staff will be very likely to leave in very quick succession after 18-30 months, once the first goes. Sure some will stay on longer, but also some of the core team may also leave. Through no fault in the team or the project, but just to go experience something else. This is completely normal in software teams. Especially once a senior long standing member goes – look and plan immediately for other to leave.
There is virtually nothing you can do to stop the flow, just accept it will happen and deal with it.

So what!

I’ve hired before, I can hire again. It’s all fine. It’s just a coupe of people.
If it’s not already clear, the short life span for a developer in one place, means if you hire lots in quick succession, they will leave in the same fashion. Unless you are still actively growing, you’re in for a bump!

It’s the wave effect

This point in time, you are no longer a start up, you no longer have a greenfield project, you no longer have the ability to just hire another dozen developers.
Also notice and look for a bit of a build up, like a wave really. Their is a feeling of general minor grumblings. Nothing major, but then once someone goes, curiosity and a question of ‘is it greener over there’ without something to cancel out these thoughts means that inertia to leaving is broken.

Managers, why?

I have to admit failing to understand this point, but senior management never wish to replace a member of staff leaving right away. They seem to like the thoughts of, well it’s only 1 person out of 40. We’ll make do without them.

Sure enough, the team does, it’s only 1 person. But that wave is building up in the rest of the team. Then the 2nd, 3rd go. By which time those leaving encourage others to go, maybe even taking there mates with them.

Know your market!

Depending on how quickly you can hire. Every market is different and you need to know where you are.

  • Maybe your company is in a software hub of a city and hiring isn’t an issue.
  • Maybe your company is in a software hub, but part of a structure that makes hiring a labourious process
  • Maybe your company is in a remote area as far as getting a pool of developers is concerned

Essentially how quickly can you get people back in that door. Are you ready to take staff out of their day jobs, plough through CV’s, then do a fair amount of hand holding to get the new staff up to speed?

Even in the best situation where your company has a low bureaucratic process for hiring, you develop in a good cultural hub/city and you have the finances to pay a potentially larger staff bill (generally a case of the best way to get a raise is to move on). You will have to take team members of active duty for transitioning in new staff.


  • Plan for people leaving – it will happen.
    If you quickly back fill a space, it will reduce the desire of others to look around. Anything fresh is a good thing, even a new face aids.
  • When you know it will take a 3 month minimum period to hire someone, never leave it for 3 or more people to leave. If you do then then even if you start hiring, those seeds of change will have sunk in already.
    Really if 3 people have left and you’ve not started looking, then you’re guaranteed that others will be on the way out (and in quick succession too, esp if they we’re all hired within a similar time frame).
  • Do not ignore unhappy staff – they’ll just leave quicker.
    You may well, and quite possibly completely disagree with your staff members reasons for being unhappy, but it’s often an open market.
    Do you want them to stay or not? If not, plan for them to go. If they stay, great, if not, then you are ready.
  • Ideally always look to the weaker area in the team. Have a range of CV’s coming in and keep the top ones for reference later. If you have potentials ready to roll, then anything you can do to reduce a gap is crucial.
  • Most importantly it can take a number of months to gain enough domain knowledge. The longer you leave it to re-hire folk,this will increase the risk of crucial knowledge being lost, which will likely lead to a major issue that could be solved quickly, but only if the domain knowledge was retained.


Stop focusing on just the technical. You need to be a team, personally as much as just work colleagues. This is SUPER hard, sometimes you want nothing more than to just do the work and go, but…

  • The grass isn’t always greener on the other side! So keeping your staff happy, when they go, they will spread the good knowledge and practices of your team.
    This can even aid in then getting new staff in, but it can also mean that staff can and will come back! Having been in many different companies, the programming world can feel like small circles at times. Just because someone left doesn’t mean they won’t wish to come back.
Array’s – Reducing all duplicates

Array’s – Reducing all duplicates

Years ago when I blogged regularly about Actionscript/Flex some of the most simple and yet popular posts were on array’s.
Today I find myself doing something similar in Javascript – and there is no out of the box solution that I’m aware off.

Take a large array (where duplicates probably exist) and condense it into a collection of unique items.

Let’s say your hitting some API and it returns 1000’s of results, and in that result you want to find out how many unique types of XXXX there are. How would you do that?
One simple way is to use an object and store the items using the key part of an object.

const duplicatedArray = [
  { name: "Bob", hairColour: "Black" },
  { name: "Jane", hairColour: "Grey" },
  { name: "Mark", hairColour: "Red" },
  { name: "Marsalli", hairColour: "Black" },
  { name: "Rachel", hairColour: "Brown" },
  { name: "Craig", hairColour: "Red" },

const getUniqueCollection = (keyFilter) => {
  const reduced = {};
  duplicatedArray.forEach((person) => {
    reduced[person[keyFilter]] = person[keyFilter];
  return reduced;

What’s going on is that it will pass only once through the array with duplication’s, and each time it will write that to the reduced object. If, as there is in this example it comes across two Black hair types then the 2nd one will overwrite the first, therefor removing any duplication.

End result, you now have an Object (some may well call this a dictionary) that on inspection contains unique list of hair colours. This for example could be used to populate a dropdown box or similar. Or you could use the below to iterate over the new object.

for (var key in uniqueCollection) {
    var value = uniqueCollection[key];
    // do something...

Lets say you’ve a more complex object!

const complexDuplicatedArray = [
  { brand: "Ford", colour: "Black", ignoredProperty: "XXX" },
  { brand: "Tesla", colour: "Grey", ignoredProperty: "AAA" },
  { brand: "VW", colour: "Red", ignoredProperty: "222" },
  { brand: "Ford", colour: "Black", ignoredProperty: "111" },
  { brand: "Tesla", colour: "Brown", ignoredProperty: "ZZZ" },
  { brand: "VW", colour: "Red", ignoredProperty: "YYY" },

// pass in ["brand", "colour"] as the parameter keyFilter
const getComplexUniqueCollection = (keyFilter) => {
  const reduced = {};
  complexDuplicatedArray.forEach((car) => {
    const keyValue = JSON.stringify(car, keyFilter);
    reduced[keyValue] = keyValue;
  return reduced;

So here we are filtering on 2 keys, the brand and the colour. Convert the object to a string and drop the properties that we do not care about.


The stringify part in the above is key. What’s it’s doing is taking an array of strings to include in the stringify process.
So using
myObj = { brand: "Ford", colour: "Black", ignoredProperty: "XXX" }
JSON.stringify( myObj, [‘brand’, ‘colour’]); will output
This is ideal for using as the key to store, so if there is another Ford car that is Black with a different property that you wish to ignore, then it’s not included.

Overriding template literal strings

Overriding template literal strings

Have you been using template literals for a while? Most likely, but did you know that you can override how it constructs the overall string? I didn’t until recently.

If you haven’t seen it, then I think you’ll be sure to think that this code is really cool and so much potential use in other areas.

It’s called tagged templates. It means that rather than calling your literal with the standard joining method, you pass your arguments to your own method.
See the below – as ever code is the best way to explain.

const person1 = "Mike";
const person2 = "Bob";

const taggedTemplateStringLiteral = myMethod`you can say hello to ${person1} and ${person2} :)`;

function myMethod(baseMessages, ...params) {
  // The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value.
  // array.reduce(callback( accumulator, currentValue[, index[, array]] )[, initialValue])
  return baseMessages.reduce((acc, cur, i) => {
    acc += `${params[i - 1]?.toUpperCase() ?? ""} ${cur}`;
    return acc;

  /*   Adding in the below as this is perhaps a more common approach,
       but as show in previous post you can improve undefined checks
       with nullish coalescing as shown in the above snippet.

    return baseMessages.reduce((acc, cur, i) => {
      acc += `${params[i - 1] ? params[i - 1].toUpperCase() : ""} ${cur}`;
      return acc;

What’s going on?

Firstly you have you grave character `. This make it into a template literal. When a string is enclosed with those then each portion (split up by using ${ } for code/var segments) is then included into an array.
Next each parameter, whatever is evaluated for each ${ } block is passed as a separate parameter. You could call them individually or in my case I used the rest (…) operator to grab them all.

myMethod`you can say hello to ${person1} and ${person2} :)`

The means to invoke the method is what caught my eye, in that you do not call it like an actual method! The above ends up being the same as –

myMethod(["you can say hello to ", " and ", " :)"], "Mike", "Bob" );

Which is rather smart and a great little snippet to remember.

Moving from IntelliJ to VS Code

Moving from IntelliJ to VS Code

Change is hard, and it’s always harder if you’ve been using ‘X’ for years.

I’ve been using IntelliJ for a number of years now, and it is great! It really is, and there is no reason other than cost not to use it. If cost is not a concern then use IntelliJ.

Keyboard shortcuts

You’ve spent years in one IDE, your fingers just know where to go, what to do. That instinctive physical memory would be very hard to get over. Any change will immediately make you less productive. You’re just not going to do it!

Thankfully the benefit of the community around VS code comes to hand.

Install this and your fingers need not learn anything new!

Unit tests

Next up is testing. I really like right clicking on a test to run/debug it. The below is a partial solution (right click to debug fails)
This requires two extensions to get it to work.

1 – Test Explorer UI

This gives you the side panel where you can see your tests – but you will see ZERO tests in here to start of with. You need to install one more extension.

2 – Jest Test Explorer

Install the below and you will now see your tests in a panel inside VS Code

You can see the list of test now inside the Test explorer.

As yet, I’m unable to get ‘debug’ to work. I can debug the entire suite of tests via a config command, but not a single test via the context menu.
This is really annoying… I’ll come back to this if/when I figure it out.


Next up is coverage mappings. You’ve run your tests, added the coverage flag and you want to see where in the code you are missing coverage.


I found that after I had installed the above, ran my coverage that nothing was being highlighted. After messing around with configuration for ages, restarting IDE etc and getting nowhere I disabled (not uninstalled) the previous extensions ( Jest Test Explorer and Test Explorer UI). After another restart of VS code, hey presto it worked!!!
Re-enabled the Test extensions and now all the extensions where working.

Not as pretty as IntelliJ, but it’s better than nothing. The colours can be customised, so this could be made less jarring on the eyes.

Code formatting – Prettier

Looking for auto format to a standard format that is widely accepted? Prettier is the way forward for many reasons. Install the above followed by a couple of config changes and your code will be beautiful.

Go to your settings, filter by ‘save’ then update to settings shown here.
“Format on Save” – True
“Auto Save” – onFocusChange


Lastly, this is a bundle of other extensions that enable things like autocomplete of filenames, autocomplete of imports. This type of hints and flow should be automatic and is there from the outset in IntelliJ. So getting the same here is a must.

Close enough…

So now that I’ve installed all of these extensions I’m really happy with VS Code. Sure it’s not as good as IntelliJ – but VS Code is FREE.
So if you want to mess around at home for some personal projects, this is brilliant.

Why all the changes in my Package-lock file?

Why all the changes in my Package-lock file?

So I’ve checked out a JS project. I’ve run npm install, this should create no changes. Yet I’m now seeing my package-lock.json file appear in the version control changed files list.

So what’s changed? It’s mainly added loads of caret’s (^) to the versions of required software packages!

So what?

Well, you may have removed all the ^ from the package file so that your node modules remained the same, and you wish to guarantee each build will be the same. Adding a new package to your dependencies should not change large sections of the lock file. Having some semblance of oversight into the changes going on in the lock file may be useful when committing. But if 90% of it changes, and those changes are pretty much the addition of ^ caret’s or changes to the patch versions then it’s really hard to see what’s actually changed.

Bottom Line

Straight to the point, what’s going on? It’s your node/npm version! Specifically difference between version 5 and 6 (npm). This can happen if you are running with node 10 (most contain npm 6+), and others are running with node 8 (contains various npm 5 versions).
So if your project started with npm 5, then someone else does an install with npm 6, then you will see the large volume of changes.

Check out what version of npm is contained in each node version here

More depth

I had trouble finding this information online, hence this blog post to hopefully aid someone else. Here are some of the source links where I found information. – Essentially the question I was looking for. – Answer on why.

Should this information disappear I’ve grabbed a screenshot as well.

An Honest WFH Experience – subjective routines

An Honest WFH Experience – subjective routines

In my previous post I highlighted what physical set up I use in order to get the most out of working from home (WFH). But that is only one half of it. You can have the best set up in the world, but that is no guarantee to successful remote working.
So here I’ll highlight the subjective/non-physical side to working from home which I believe makes it work, and work well.


I’m putting this one at the top of my list. Personally I think this is key to being able to enjoy working from home. You must enjoy your job, and coding is fun (when it works…), but if that’s it then even that can become dull. You’ll get those crap days where nothing works and if you only enjoy the coding, then where are you? 🌧 β›ˆ 🌨

So what can you do? Make sure to say “Hi” first thing, just like you would in the office. Let folk know you’re there, and likewise say “bye” at the end of the day.
Note – I must do this more!

Get a Camera

Make sure you have a web camera. People are very expressive and as such our face can speak without speaking, the amount of non verbal communication you get over a camera is immense. Even for those that seriously dislike cameras, or if you feel your home office is a bit messy, ignore that and turn it on. Others will appreciate it.

“no more than 30 to 35 percent of the social meaning of a conversation or an interaction is carried by the words.”

Ray Birdwhistell The Kinesics Report

Casual chats

Work is never only about work, how many times would you walk past someones desk and say hello and have a wee chat about life? Or bump into someone in the kitchen and discuss what happened the other day while making a cup of tea.
Well, make sure you do this during your WFH days. Set up a time, at least twice a day to open up a video conference chat (Zoom is great) and do just that. Discuss what’s happening and listen to others.

Stick it in your calendar

As discussed above, in order to keep it up, you must put it into your calendar. Plan it out. These things will not just happen. We, inside our team set aside time for casual chats at least twice a day. May seem a little formal setting aside time, but if you don’t, then it won’t happen.
Conversations range from the weekend to what you may be working on and that’s a good thing.

Ultimately this is extremely rewarding as a team.

Don’t underestimate being a team, when things go wrong – and they will, when you’re stuck, when you’ve created a stinker of a bug, or broken the pipelines etc, being able to have a communication channel open will save your day and keep the team together.


Having your office in your house is hard. Are you ever away, do you ever switch off? Does the room where you work now turn into a no go zone after hours?
Now the following will depend entirely on your property – but do your utmost to create an office space. You NEED somewhere that you can shut off when you are done. Maybe if you don’t have space outside like myself for a shed/cabin, set up your desk in a room you don’t use. Maybe you stay with your parents or your flat mate is in the same situation as you. Swap rooms during the day.
Make your desk in that room, so once you are done, you don’t go back to that room.
Whatever you do, try really hard to find somewhere that you can close the door at the end of the day. So the livingroom will most certainly be the worst place! If you have it here, then you’ll not be able to have a relaxing time after a stressful day.

Hopefully that gives you a little bit of insight or ideas for your own WFH set up. Below is a small capture of the benefits and drawbacks that I’ve found when WFH.

What’s great

  • No travelling. This is great as I no longer have to pay Scotrail a small fortune each day.
  • I’m using my ‘extra’ time to do some daily exercise (… πŸ˜‚, well almost).
  • Being at home for dinner with the family – kids really like this as well!
  • Having lunch/teas/biscuits brought out to my office 😎🍰
Time spent with family is a great benefit – much better than commuting!

What’s not so great

  • Missing my 50-60 mins travel each way where I can sit down and do my own thing on the train πŸš…
  • Not being able to turn around and chat to colleagues.
  • Not being part of the bigger team/office.
  • Lack of community events.

An Honest WFH Experience – the set up

An Honest WFH Experience – the set up

An actual working from home set up! Not some manicured or cleaned up rig. But this is a functional, productive live coding environment.

Not the cleanest or slickest set up – but I really like it!

So the world is in lock down, or at least large parts of it are. Covid-19 has hit and in order to spare a complete meltdown of our health services we are all working from home where possible.

Thankfully developers have the ideal job when required to work from home (WFH). We can do our job from anywhere as long as it has some form of data connection – even that we can do without for a bit!

Location and surrounding don’t matter to dev’s

So getting to the point, what do I do that is different from others? I’m going to break this into two posts.

  1. My physical set up. (this post)
  2. My daily routine, with positives and negatives.

Set Up

Firstly, you may be used to having all your IT equipment paid for and purchased for you by your employer, and as such your home set up may only consist of a single laptop.

This will not cut it! From a personal view point, it will frustrate you, it will get you down, it will slow you down. This will ultimately lead you to become unhappy and stressed. Stress does not lead to good code and will lead you down a path to grey hairs and sleepless nights. πŸ˜‰

Many screens keep context switching simple

Developers can earn a very good wage and purchasing a few screens or a desktop will not break the bank, think of it as an investment in you and your career. If your employer will pay for something then great! Take it, even the smallest of percentage gains in productivity will more than pay off and keep you happy.
If there is one thing that makes you feel good being a developer, it’s completing a task. The more you get done the better you feel.

It’s to easy to flip from being awesome to banging your head. A good set up will save you entering the painful state so often!

Ultimately a great, comfortable set up will make you more productive, contented, calm and happier, this is a win for all. The Covid-19 lock down is expected to be months, do you really wish to stare and a small 15″ laptop screen for 3-4 (maybe 8+) months!

I really can’t stress this enough – get yourself more visual real estate.


Microsoft mouse without borders –

This is an brilliant piece of software and free! Sure I’d like it to do a wee bit more, but it’s free. So you’ve got your small laptop, but now taken the plunge to get something to handle a few more screens. Can you use both at the same time without the hassle of two keyboards and two mice? YES.

Install Mouse without borders, now you control both machines (it can do more than two as well) without the clutter. But why should you do that? Does it really gain anything?

Two machines

Main One

My main machine (tower pc) is for code, work, emails and all that involves day to day operations. The reason for this is so I can get a powerful graphic card, get one that will drive 3 or 4 monitors. If I had space I’d have 4, but 3 screens is enough πŸ™‚

The actual tower PC doesn’t need to be a powerhouse machine, especially if you remote into a secure remote desktop, which means your machine doesn’t need to do any real processing. Your circumstances may vary, but in all my years I’ve never ‘needed’ a top of the range machine. I may have wanted it, just because, but never needed it!

Machine Two

The laptop, and this is key for collaboration. It is used for communication. Being stuck apart from your colleagues is hard, and when you are working on spec’ing out a system or creating new configuration for which you may not have all the required knowledge, then having someone to speak to and bounce ideas off is invaluable.

So start up a Zoom conference call, stay on it all day if needed, keep the face to face open until you solve the issue. You can screen share on your main machine while being able to see and speak on the dedicated communications machine.

Until you reach a situation where this type of communication is required, this may seem like overkill. But once you understand the value of communication, the easier this is and the more human it can become, the more you’ll understand that it is worth every penny. We are beings that like to communicate, yes even developers 😎 Use technology to make this as natural as possible.

Am I at home or my office?

This part is one where it will be very difficult for most to do if you live in a very built up area, but if you can then you should! In terms of mental state, being able to work effectively and the switch off at the end of the day, this one is a HUGE winner.

You need to be able to leave your house!

What? How on earth can I leave my house, I’m in lock down? Well you need another building on your premises. If you have a few spare square meters then you probably have enough room to build a shed. There are plenty of log cabin kits out there, again not very expensive, depending on what you go for.

A small cabin can set you back less than a Β£1000

Get one of these set up, get some power and some heat in there, add a bit of insulation and you are good to go!

Is it worth it? 100% it is. You walk out your back door, leave the home behind and you are now at work. The mental separation is so clear, and what’s more – do you have children? Yes, then yes you can close the door, no screaming kids to disturb that all important thought process. What’s more they’ll love it when they can come in.

Then at the end of the day, turn it off, close the door and you are done.


Space and screens

Get those two things right and you will be as productive as being in any office in any part of the world.

Verify the checksum of an installer file

Verify the checksum of an installer file

One of those regular items you see when downloading a file.

What’s that checksum, how to I check it?

Quick solution if you are on a Windows machine.

  • Open the folder that you’ve downloaded the file to – probably the download folder
  • Inside the path bar, type cmd, then press enter
Enter cmd into the path bar
  • You will now have a command window open that is already looking in the download folder.
  • Now type the following certutil -hashfile {file name you are checking goes here} {check type, as in MD5 or SHA1 for example}
  • eg certutil -hashfile myDownloadedFile.exe SHA1
  • This will now output something like the below with a SHA-1 check

You can now compare the long number with the number on the download page, if they do not match DO NOT INSTALL.

Other checks you can do depending on what the website is asking for are these –
Hash algorithms: MD2 MD4 MD5 SHA1 SHA256 SHA384 SHA512

Clever Code

Clever Code

Getting into JS and come across code that many will consider ‘clever’ code. Is this code that is unreadable or is it the features that the language provides? I’m not really going to get into that discussion here – this post will hopefully instead help show and explain what is going on with such code. So should you see it then you’ll be able to understand what is going on and maybe even use it yourself.

const selective = [
    { id: "firstObjectId", ...obj1 },
    { id: "secondObjectId", ...obj2 },
    ...(obj3 ? [{ id: "thirdObjectId", ...obj3 }] : [])

What’s the aim of this code?

The aim of the above is to inject an ID into every object and at the same time it will only return two items if obj3 does not exist, and 3 if it does.


You may wish to combine a series of requests and sometimes you expect one of the requests to come back with nothing. If it does then there will be no need to return the 3rd element as an empty object – just drop it.


Part 1 – What is { id: “firstObjectId”, …obj1 } doing? It’s taking the values from obj1, spreading them into another object while at the same time including an ID value. So it’s a new object with an ID as well as everything that was inside obj1 to start with.

What about …(obj3 ? [{ id: “thirdObjectId”, …obj3 }] : [])
Well if obj3 exists then it’s the same as the previous lines.
If it doesn’t exist then the line of code is

const selective = […([])]
which is


As the array is empty the spread operator will take nothing out of an empty array which leaves an empty array!
So we combine that with with the other spread objects and we now have a neat means of checking if an object exists and only if it does then include it in a returned item.

Old School

If this were in old school code it would look something like this

const returned = [
{ id: "firstObjectId", ...obj1 },
{ id: "secondObjectId", ...obj2 },
if (obj3) {
returned.push({ id: "thirdObjectId", ...obj3 });

So you are including an ‘if’ and then pushing the item into the array. Not quite as elegant!