[#106355] [Ruby master Bug#18373] RBS build failure: '/include/x86_64-linux/ruby/config.h', needed by 'constants.o'. — "vo.x (Vit Ondruch)" <noreply@...>
Issue #18373 has been reported by vo.x (Vit Ondruch).
28 messages
2021/12/01
[ruby-core:106442] [Ruby master Feature#18181] Introduce Enumerable#min_with_value, max_with_value, and minmax_with_value
From:
"matz (Yukihiro Matsumoto)" <noreply@...>
Date:
2021-12-03 05:04:57 UTC
List:
ruby-core #106442
Issue #18181 has been updated by matz (Yukihiro Matsumoto).
Just for confirmation, is it OK that `min_with_value` returns only a single value?
I don't like the name `_with_value`. It explains that the method returns an additional value with the minimum/maximum value, but no additional information on the value.
Matz.
----------------------------------------
Feature #18181: Introduce Enumerable#min_with_value, max_with_value, and minmax_with_value
https://bugs.ruby-lang.org/issues/18181#change-95087
* Author: kyanagi (Kouhei Yanagita)
* Status: Open
* Priority: Normal
----------------------------------------
PR is https://github.com/ruby/ruby/pull/4874
I propose `Enumerable#min_with_value`, `max_with_value` and `minmax_with_value`.
These methods work like this:
``` ruby
%w(abcde fg hijk).min_with_value { |e| e.size } # => ['fg', 2]
%w(abcde fg hijk).max_with_value { |e| e.size } # => ['abcde', 5]
%w(abcde fg hijk).minmax_with_value { |e| e.size } # => [['fg', 2], ['abcde', 5]]
```
Corresponding to `#min(n)`, an integer argument can be passed to `#min_with_value` or `#max_with_value`.
``` ruby
%w(abcde fg hijk).min_with_value(2) { |e| e.size } # => [['fg', 2], ['hijk', 4]]
%w(abcde fg hijk).max_with_value(2) { |e| e.size } # => [['abcde', 5], ['hijk', 4]]
```
## Motivation
When I use `Enumerable#min_by`, I sometimes want to get not only the minimum element
but also the value from the given block.
(e.g.: There are many points. Find the nearest point and get distance to it.)
``` ruby
elem = enum.min_by { |e| foo(e) }
value = foo(elem)
```
This works, but I'd like to avoid writing foo() twice. (Consider a more complex case.)
This can be written without repeated foo() like belows, but it is slightly complicated and needs extra arrays.
``` ruby
value, elem = enum.map { |e| [foo(e), e] }.min_by(&:first)
```
If the size of enum is enormous, it is hard to use intermediate arrays.
`Enumerable#min_with_value` solves this problem.
I think `min_with_value` is the best name I could think of, but any suggestions for better names would be appreciated.
## Benchmark
https://bugs.ruby-lang.org/issues/18181#note-2
## Example
Solving a traveling salesman problem in nearest neighbor algorithm.
``` ruby
require 'set'
Point = Struct.new(:x, :y)
points = Set.new([Point.new(1, 1), Point.new(2, 4), Point.new(3, 3), Point.new(2, 2), Point.new(0, 1)])
total = 0
current = points.first
points.delete(current)
path = [current]
until points.empty?
current, distance = points.min_with_value do |point|
Math.hypot(current.x - point.x, current.y - point.y)
end
total += distance
points.delete(current)
path << current
end
p path
p total
```
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>