Tuesday, May 21, 2024
HomeRuby On RailsRuby group_by or Rails group_by

Ruby group_by or Rails group_by


The aim of this text is to grasp the group_by technique from a theoretical and sensible perspective, each for Ruby, and Rails.

What’s the group_by technique in Ruby?

The .group_by technique is included in Ruby’s Enumerable module.
Now we have already written in regards to the Enumerable module and Enumerators in earlier weblog entries.
That is due to the significance of those ideas, as they’re key to interacting with knowledge: iterating by way of collections of components, looking out, fetching and sorting, amongst different options.

group_by: The definition

As per Ruby’s Documentation, the group_by technique kinds a group of knowledge in accordance with a situation handed as a block.

group_byfactor -> hash

Right here, being the block: ....

Essential points

  • When utilizing group_by with a block, the result’s a hash. The hash is constructed of keys and values:
  1. Keys: Are returned values of the block
  2. Values: Within the type of an array, which represents the matching components of the gathering for every key
  • When utilizing group_by with no block, the result’s an Enumerator.

In different phrases, when utilizing this technique we at all times want a assortment of objects (knowledge) and a grouping rule (block).

One of many fundamental examples to grasp the logic of group_by is grouping a set of strings by its first letter:

%w(apple apricot banana orange avocado beetroot).group_by  factor[0]
# => return:
{
  a: ["apple", "apricot", "avocado"],
  b: ["banana", "beetroot"]
  o: ["orange"]
}

On this instance, we are able to clearly determine the completely different points defined above:
The gathering of objects: the array %w(apple apricot banana orange avocado beetroot)
The grouping rule: the block, which iterates by way of the weather of the array and fetches the primary letter of every factor
The hash: the results of the tactic, containing the keys (completely different beginning letters within the assortment) and values (components of the gathering that begin with every key)

Utilizing group_by on a Hash

When creating purposes and person interfaces with Ruby-on-Rails we use object-oriented-programming language, which implies we construct the applying based mostly on objects. That is why it is extremely sensible to have the ability to apply the group_by technique on hashes.

For instance, if now we have an software with completely different person standing (lively and inactive):

user_status = {
  mary: "lively",
  peter: "inactive",
  rose: "lively",
  hans: "lively",
  cristian: "lively",
  claire: "inactive"
}

We are able to group them as per beneath, utilizing a a number of line block:

user_status_grouped = user_status.group_by do |person, standing|
  standing = "lively" ? :is_active : :is_inactive
finish

# => return:
{
  is_active: [
    ["mary", "active"],
    ["rose", "active"],
    ["hans", "active"],
    ["cristian", "active"]
  ],
  is_inactive: [
    ["peter", "inactive"],
    ["claire", "inactive"]
  ]
}

This type of hash (object) may be very helpful as a result of it’s a quick means of organizing knowledge after which accessing it by key. For instance, if we wish to get all inactive customers:

user_status_grouped["is_inactive"]

# => [["peter", "inactive"],["claire", "inactive"]]

We are able to mix different strategies as a way to deal with the ensuing array as per our wants. On this case, we are able to use the strategies flatten and `delete :

inactive_users = user_status_grouped.flatten.delete("inactive")

# => ["peter", "claire"]

The tactic flatten transforms the multiple-dimension array right into a one-dimension array. And the delete is used to simplify the information and acquire solely the person names of these customers who’re inactive.

Sensible instance: Rails Utility

When working with actual purposes, it’s particularly helpful to carry out the above train with person ids as a substitute of names. It’s because person ids are distinctive values linked to every person (object) and it’s best apply to depend on them. Additionally, with the ids, it’s simpler to make use of objects as inactive_users to iterate by way of different objects and match the customers.

Let’s have a look at an instance and picture inactive_users is now containing Peter’s and Claire’s ids (123 and 321 respectively):

p inactive_users
# => [123, 321]

Additionally, now we have an object (hash) referred to as last_connection which comprises the final time a person was related to the applying:

p last_connection
# =>  
{
  111: ["22-04-19 12:00:11"],
  123: ["20-11-02 13:00:17"],
  233: ["22-06-18 18:33:23"],
  321: ["21-04-25 09:10:00"],
  ...
}

Now we are able to loop by way of the inactive customers and fetch the final connection date and time stamps for every inactive person (person id):

inactive_last_connection = []

inactive_users.every do |person|
  inactive_last_connection << [user, "#{last_connection[user]}"]
finish

p inactive_last_connection

# => [[123, "20-11-02 13:00:17"], [321, "21-04-25 09:10:00"]

GROUP BY with Lively Report from Rails

As said on this StackOverflow reply, if you wish to set off a GROUP BY sql assertion due to Lively Report, you are taking inspiration from this instance :

Individual.group(:identify).rely
(1.2ms)  SELECT COUNT(*) AS count_all, identify AS identify FROM "individuals" GROUP BY "individuals"."identify"
=> {"Dan"=>3, "Dave"=>2, "Vic"=>1} 

Conclusion

There are 3 important conclusions that may be extracted from this evaluation:

  1. The Enumerable Module may be very highly effective and you will need to grasp its strategies, resembling group_by.
  2. In object-oriented-programming languages, it’s key to have other ways to construction and manipulate knowledge as effectively as attainable.
  3. The above points are crucial when constructing purposes. The aim is to save lots of reminiscence area and assure velocity and efficiency.
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments