5 Array Methods Ruby and JavaScript Share and their Subtle Differences

Daniel Pericich
9 min readFeb 28, 2021

--

‘image: Flaticon.com’. This cover has been designed using resources from Flaticon.com

A few weeks ago I accepted an offer to work for my new company, Whitelabel. While most of my prior programming experience had been in JavaScript, Clojure, R and some Python, my first project would be primarily Ruby and Rails. After learning one language well, learning another language comes down to understanding syntax differences and utility functions.

With this in mind, I completed a Codecademy Ruby primer, subscribed to Medium’s Ruby blog daily newsletters and started working through LeetCode and HackerRank questions to get more familiar with the Ruby language and all its quirks.

One thing that I was happy to see transferred from JavaScript to Ruby was the use of common array methods. Old friends such as forEach, map and filter were all here. While some of the names changed, and some methods required additional chained methods for full functionality, I found that if you understand JavaScript array methods, you are well on your way to mastering Ruby.

In this article I will go over some of the common array methods shared between JavaScript and Ruby and differences that exist between the two languages.

JavaScript’s forEach and Ruby’s each methods

The most basic operation for array methods is to simply iterate over each item in the array. Ruby has the each method for doing just that. The each method accepts a list of arguments and then a block to perform on each argument. This method is great if you want to run an operation on each item in the list, but don’t care about returning a tidy array:

Figure 1: Ruby’s each array method

JavaScript’s forEach method does the same operation, accepting a list of arguments and logic to apply to each item in this list. Like each, it does not return an array with the result of the operations performed on each array item. To return a results array as a value, you will need to use the method discussed in the next section. Here is an example of forEach in action:

Figure 2: JavaScript’s forEach array method

Before we move on, I would like to talk about some key differences between Ruby and JavaScript array methods. Ruby is very flexible in how you are able to use these methods. With Ruby, these methods can be applied to both arrays and hashes. If we wanted to iterate over a hash using each, we would just define the key and value as arguments for our block instead of a single value argument:

Figure 3: Ruby’s each method applied to a hash

This flexibility allows us to skip steps we would have to do in JavaScript such as converting an object to an array in order to iterate over it. It also save us from using the less specific for in loop structure for iterating over objects. The ability to iterate over hashes with array methods is due to Ruby’s Enumerable classes which extends this traversal ability to arrays, hashes and range objects. If you’d like to learn more about the Enumerable module, check out the first link in my resources.

While JavaScript does not support hash and range iteration, it makes up for this by not requiring extra method chaining in order to allow users access to extra parameters. For example, to have access to both the current item in the array as well as that item’s index value, we could write something like this in JavaScript:

Figure 4: JavaScript array method with access to index

However to get the same access to the index with Ruby’s each, we will have to change the name of the each method to each_with_index:

Figure 5: Ruby array method with access to indices

We don’t lose the ability to access the index between the two languages, but as you will see in later array methods, the extra syntax can be a confusing headache.

JavaScript’s map and Ruby’s map and collect methods

The each and forEach array methods are great if you don’t care about holding onto your transformed arrays. If you do want to hold on to them to use in a later function, you will need to use the map method.

Similar to the each method, map accepts a list of items as well as a block or set of operations to perform on each item. Where these methods differ is that map will return the modified list. It is important to remember that modifying is not the same as mutating. In modifying the list, we have a method that returns the new list, but does not change the original list. If we mutate the list, we are overriding the original list’s items and will lose the original values.

In order to save the map method’s operations, we will need to assign the returned value to a new variable:

Figure 6: JavaScript map method

Now, we have access to both the original variable prices and modified prices stored in the salesPrices array. In Ruby we are able to skip the step of reassignment to a new variable by adding a “!” to the end of the method:

Figure 7: Ruby map method with mutation modifier

Doing this will modify the original list in place. The original list’s contents will be permanently replaced with the mapped values. Ruby uses the “!” on the end of array methods to alert the user that what they are doing is dangerous. Mutating arrays is not often encouraged, as it effectively overwrites information that could be important later in the program. Be very mindful of using this modified on your methods.

JavaScript’s filter and Ruby’s select methods

A very common operation to perform on arrays is to iterate over elements and return a new array containing only certain elements based on a condition. To perform this, we use the filter method in JavaScript and the select method in Ruby.

How do these methods know whether to keep or discard an item as they iterate? Within the block for Ruby, or callback for JavaScript, you pass in an expression that will evaluate true or false. If the expression evaluates true, you keep the value and it will show up in the return array. Here are both of these languages versions of the filter method:

Figure 8: Ruby and JavaScript’s filter mtethods

I did not find any major differences between filter and select beyond the basic syntax, and Ruby’s need for modifiers to access extra arguments such as current index. There were two things that I found very interesting in the Ruby docs.

First, in Ruby 2.6 and later versions, filter was added as an alias for select. This means that if you are using a newer version you can use filter instead of the select method name for filtering operations. I also found that find_all is interchangeable with select. Ruby offers 3 method names to accomplish the same goal of filtering an array for the values you need.

Whether you use filter, find_all or select, you can rest easy knowing that you will get similar results in both Ruby and JavaScript.

** A quick note on Ruby on Rails: select has a very different meaning when used to query with ActiveRecord. In this context, select takes an array of symbols for the column names and will return only these columns from a specified model

JavaScript and Ruby’s Pop, Shift, Push and Unshift Array Methods

I was recently working through an array question on HackerRank that focused on performing left rotations on an input array. Doing this in JavaScript would be simple enough. All you would have to do is call a for loop with n iterations, where n is the number of times the iteration is called for, and each iteration would shift the array one element You could then store this element in an intermediate variable and finally push the shifted element back to the end of the array.

Ruby and JavaScript had similar approaches, but with one difference. The main difference in these approaches came in how to loop over the action of shifting. Because Ruby does not support for loops the same way JavaScript does, I used the times method, passing it the rotation block to complete n times. It was different, but got the job done in O (N) time:

Figure 9: Performing a left rotation in Ruby

I was excited to find that this approach, and the methods involved with it, was identical between Ruby and JavaScript. In this approach I used two of four common element array methods, push and shift. Shift removes the first element of an array and returns the value to you, and push adds a new value to your array. There corresponding opposite methods are pop and unshift.

An important thing to remember with these four array methods is that they do mutate, or permanently change, the array. When you add (push, unshift) or remove (pop, shift) an element of the array, you do not have to reassign the resulting array to a new value to save the change.

Another thing to remember when working with pop and shift is you need to assign the removed element’s value to a variable to be able to use it later in the program. Besides getting used to the different approaches to iteration, Ruby and JavaScript are nearly identical for these methods.

JavaScript and Ruby reduce methods

If you’ve ever needed to get the sum of all items in an array, you’ve probably used the reduce method. This method is great for tasks such as determining the total cost of items in a shopping cart or summing items in an array to get the average of a set.

In the simplest terms, reduce takes an array of items and reduces these items to a single value. When it came time to use this method in Ruby, I found that while this operation shares the same reduce method name with JavaScript, there were a number of differences in how it is implemented. Below are examples of both the JavaScript and Ruby reduce methods in action:

Figure 10: Reduce method in JavaScript and Ruby

Reduce has three main arguments that it uses to determine the single value to return. These arguments are the accumulator, the current value and the initial value. The initial value is what you set for when the reduce method starts. If you are summing the values of the array, you will want to set this to 0 so that you do not have extra value added to your sum.

Inside the callback or block, we have the accumulator and current value. The accumulator is the variable that stores the running total value throughout the reduce operation. The current value allows you to access the current array item for whatever iteration count you are on.

Along with these, you are able to set an initial value for the accumulator. This is where the first difference appears. In JavaScript, the initial value is set as the second argument to the reduce method, after the callback. However, in Ruby the initial value is passed as the only argument to the reduce method.

Final Thoughts on Array Methods

After spending time working in multiple languages I expected the transition from JavaScript to Ruby to be much more challenging. What I have found is that many of the array methods that were so useful in JavaScript are present and mostly the same in Ruby.

If you would like to learn more about these or other methods, I highly recommend visiting MDN for more information on JavaScript, or any of the many Ruby doc sites. Happy iterating!

Resources

https://blog.appsignal.com/2018/05/29/ruby-magic-enumerable-and-enumerator.html

https://mixandgo.com/learn/how-to-use-ruby-each

https://www.rubyguides.com/2018/10/ruby-map-method/

https://medium.com/better-programming/6-advanced-ruby-loops-13695c20d012

https://blog.appsignal.com/2018/05/29/ruby-magic-enumerable-and-enumerator.html

https://medium.com/@james.a.hughes/using-the-reduce-method-in-ruby-907f3c18ae1f

--

--

Daniel Pericich
Daniel Pericich

Written by Daniel Pericich

Former Big Beer Engineer turned Full Stack Software Engineer

No responses yet