Given an array of complex objects, an algorithm for mapping each to Comparable values, and the desire to find the minimum such value, is there a built-in library method that will do this in a single pass?
给定一个复杂对象数组,一个将每个对象映射到可比值的算法,以及找到最小值的愿望,是否有一个内置的库方法可以在一次遍历中完成这个操作?
Effective but not perfectly efficient solutions:
有效但不是完全有效的解决方案:
# Iterates through the array twice
min = objects.map{ |o| make_number o }.min
# Calls make_number one time more than is necessary
min = make_number( objects.min_by{ |o| make_number o } )
Efficient, but verbose solution:
有效,但详细的解决方案:
min = nil
objects.each{ |o| n=make_number(o); min=n if !min || n<min }
1 个解决方案
#1
5
No, no such library method already exists.
不,目前还不存在这样的库方法。
I don't really see an issue with either of your two original solutions. The enumerator code is written in C and is generally very fast. You can always just benchmark it and see what is fastest for your specific dataset and code (try https://github.com/acangiano/ruby-benchmark-suite)
我不认为你的两个原始解决方案有什么问题。枚举数代码是用C编写的,通常非常快。您可以对它进行基准测试,并查看特定数据集和代码的最快速度(请尝试https://github.com/acangiano/ruby-benchmark-suite)
However, if you really do want one pass, you can simplify your #each
version by using #reduce
:
然而,如果你真的想要一个通过,你可以简化你的#每个版本通过使用#reduce:
min = objects.reduce(Float::INFINITY){ |min, o|
n = make_number(o)
min > n ? n : min
}
If your objects are already numbers of some form, you can omit the Float::INFINITY
. Otherwise, in order to make sure we are only comparing number values, you will need to add it.
如果你的对象已经是某种形式的数字,你可以省略浮点数::∞。否则,为了确保我们只是比较数字值,您将需要添加它。
#1
5
No, no such library method already exists.
不,目前还不存在这样的库方法。
I don't really see an issue with either of your two original solutions. The enumerator code is written in C and is generally very fast. You can always just benchmark it and see what is fastest for your specific dataset and code (try https://github.com/acangiano/ruby-benchmark-suite)
我不认为你的两个原始解决方案有什么问题。枚举数代码是用C编写的,通常非常快。您可以对它进行基准测试,并查看特定数据集和代码的最快速度(请尝试https://github.com/acangiano/ruby-benchmark-suite)
However, if you really do want one pass, you can simplify your #each
version by using #reduce
:
然而,如果你真的想要一个通过,你可以简化你的#每个版本通过使用#reduce:
min = objects.reduce(Float::INFINITY){ |min, o|
n = make_number(o)
min > n ? n : min
}
If your objects are already numbers of some form, you can omit the Float::INFINITY
. Otherwise, in order to make sure we are only comparing number values, you will need to add it.
如果你的对象已经是某种形式的数字,你可以省略浮点数::∞。否则,为了确保我们只是比较数字值,您将需要添加它。