Project

General

Profile

Actions

Feature #18135

open

Introduce Enumerable#detect_only

Added by meisel (Michael Eisel) 2 months ago. Updated about 2 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:105074]

Description

It can be important to get the only element for which a block returns true, and to assert that this is the only element as such. For example, this can be a very helpful sanity check when one is working with data that's outside of their control and is not perfectly understood. They may have a guess as to how to get a specific element matching some criteria, but if they used Enumerable#detect might be hiding the fact that they have written an incorrect block and that there's in fact more than one element that matches it. It could also be a parameter on Typically, I'd do it like this:

matches = array.select { |elem| some_method(elem) }
raise if matches.size != 0
match = matches.first

Here, it would be shortened to:

match = array.detect_only { |elem| some_method(elem) }

It could also be a parameter on Enumerable#detect instead of a separate method.


Related issues

Related to Ruby master - Feature #13683: Add strict Enumerable#singleFeedbackActions
Actions #1

Updated by jeremyevans0 (Jeremy Evans) 2 months ago

  • Backport deleted (2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN)
  • Tracker changed from Bug to Feature

Updated by meisel (Michael Eisel) about 2 months ago

Also, another alternative could be Enumerable#take_only, where it takes the only element from the enumerable or else fails. So instead of:

array.detect_only { |elem| some_method(elem) }

We'd have:

array.select { |elem| some_method(elem) }.take_only

Updated by duerst (Martin Dürst) about 2 months ago

meisel (Michael Eisel) wrote in #note-2:

Also, another alternative could be Enumerable#take_only, where it takes the only element from the enumerable or else fails. So instead of:

array.detect_only { |elem| some_method(elem) }

We'd have:

array.select { |elem| some_method(elem) }.take_only

It's a good idea to separate things out, but this could be highly inefficient (checking and selecting lots of elements only to find out later that there's more than one).

Actions #4

Updated by mame (Yusuke Endoh) about 2 months ago

Updated by mame (Yusuke Endoh) about 2 months ago

Do you mean raise if matches.size != 1 instead of ... != 0?

The idea of take_only is already proposed in #13683.

Updated by meisel (Michael Eisel) about 2 months ago

Yes, I meant ... != 1, thanks. And I think we can close this issue, and I'll add my thoughts to the issue that this dupes.

Actions

Also available in: Atom PDF