How to Map and Remove Nil Values in Ruby

How to map and remove nil values in Ruby

Ruby 2.7+

There is now!

Ruby 2.7 is introducing filter_map for this exact purpose. It's idiomatic and performant, and I'd expect it to become the norm very soon.

For example:

numbers = [1, 2, 5, 8, 10, 13]
enum.filter_map { |i| i * 2 if i.even? }
# => [4, 16, 20]

In your case, as the block evaluates to falsey, simply:

items.filter_map { |x| process_x url }

"Ruby 2.7 adds Enumerable#filter_map" is a good read on the subject, with some performance benchmarks against some of the earlier approaches to this problem:

N = 100_000
enum = 1.upto(1_000)
Benchmark.bmbm do |x|
x.report("select + map") { N.times { enum.select { |i| i.even? }.map{ |i| i + 1 } } }
x.report("map + compact") { N.times { enum.map { |i| i + 1 if i.even? }.compact } }
x.report("filter_map") { N.times { enum.filter_map { |i| i + 1 if i.even? } } }
end

# Rehearsal -------------------------------------------------
# select + map 8.569651 0.051319 8.620970 ( 8.632449)
# map + compact 7.392666 0.133964 7.526630 ( 7.538013)
# filter_map 6.923772 0.022314 6.946086 ( 6.956135)
# --------------------------------------- total: 23.093686sec
#
# user system total real
# select + map 8.550637 0.033190 8.583827 ( 8.597627)
# map + compact 7.263667 0.131180 7.394847 ( 7.405570)
# filter_map 6.761388 0.018223 6.779611 ( 6.790559)

Remove nil values from array and corresponding entries from reference array

First, filter by nil. Then break that up into two arrays.

@last_dividends = @dividends.historical.select { |d| d.dividend }
@dividends_values = @last_dividends.map(&:dividend)
@dividends_dates = @last_dividends.map(&:date)

Better yet, turn them into a single array of [[dividend, date], [...]]

@last_dividends = @dividends
.historical
.select { |d| d.dividend }
.map { |d| [d.dividend, d.date] }

Ruby remove nil values from array with .reject

It is as simple as:

scores.grep(Integer)

Note that if you plan to map the values, you can do that in a block after:

scores.grep(Integer){|x| x+1 }

Bonus if you want to do the same thing, but your numbers are strings:

scores.grep(/\d+/){|x|x.to_i}

How do I find and replace 'nil' values of Ruby hash with None or 0?

each won't "persist" the value you're yielding within the block. Try map instead.

def self.replace_nil(record) 
record.map do |r|
r.values.nil? ? "None" : r.values
end
end

In fact, there's a method for that; transform_values:

record.transform_values do |value|
value.nil? ? 'None' : value
end

I realized that using Rails you can use just presence and the or operator:

record.transform_values do |value|
value.presence || 'None'
end

Remove nil values from hash

The given input is valid JSON, and the question has the JSON tag, so I'd like to offer a generic solution to the problem of recursively eliminating keys in JSON objects, wherever they occur, and no matter what the input JSON may be.

The solution is written in a new JSON-oriented programming language, jq, but even if you cannot use jq, the solution is so brief and elegant that it may suggest an implementation to the general problem in your language of choice.

Here it is - a one-liner:

walk( if type == "object" then with_entries( select(.value != null) ) else . end)

This presupposes jq version 1.5 (see https://stedolan.github.io/jq/).

If you have an older version of jq, the definition of walk/1 can easily be added. (See e.g. Transforming the name of key deeper in the JSON structure with jq)

Remove nil and blank string in an array in Ruby

You could do this:

arr.reject { |e| e.to_s.empty? } #=> [1, 2, "s", "d"]

Note nil.to_s => ''.



Related Topics



Leave a reply



Submit