Однострочник для «возврата объекта, если найден» - PullRequest
3 голосов
/ 27 июня 2019

В настоящее время я использую этот код для прямого возврата объекта из функции, если он найден в массиве:

already_existing = my_array.find { |v| ... predicate ... }
return already_existing if already_existing
# ...
# Remaining of the function should be executed if object not found

Существует ли элегантный способ преобразовать его в однострочник?

Примечание : Без вызова find дважды, конечно, или без вызова include? сначала, затем find, потому что это приведет к снижению производительности)

Ответы [ 3 ]

4 голосов
/ 27 июня 2019

Вы можете использовать короткое замыкание.

my_array.find { |v| ... predicate ... } or begin
  # the other logic
end

Но я бы лично пошел с return existing if existing. Это тот случай, когда излечение хуже болезни.

0 голосов
/ 29 июня 2019

Есть ли элегантный способ превратить его в однострочник?

Конечно, есть!Фактически, поскольку в Ruby необязательные символы новой строки, любая произвольно сложная программа Ruby может быть превращена в однострочник:

already_existing = my_array.find { |v| ... predicate ... }; return already_existing if already_existing
0 голосов
/ 28 июня 2019

Библиотека Facets имеет метод #find_yield. Это может помочь организовать код в одну строку. Также это можно сделать с помощью комбинации map.detect. В основном вам нужно сделать return something that found OR call other stuff:

require "facets"
test_arrays = [[1, 2], [1, 2, 3]]

# with facets library
test_arrays.each do |my_array|
  puts my_array.find_yield{ |i| j = i + 1; j if j % 4 == 0 } || "other_logic_result"
end
# => other_logic_result
# => 4

# with pure ruby methods
test_arrays.each do |my_array|
  puts my_array.lazy.map { |i| i + 1 }.detect { |j| j % 4 == 0 } || "other_logic_result"
end
# => other_logic_result
# => 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...