草庐IT

c# - 带有非传递 IComparer 的 OrderBy

coder 2024-05-31 原文

采用自定义 IComparer,如果两个 double 的差异小于给定的 epsilon,则将其视为相等。

如果在 OrderBy().ThenBy() 子句中使用此 IComparer 会发生什么情况?

具体来说,我在考虑以下实现:

public class EpsilonComparer : IComparer<double>
{
    private readonly double epsilon;

    public EpsilonComparer(double epsilon)
    {
        this.epsilon = epsilon;
    }

    public int Compare(double d1, double d2)
    {
        if (Math.Abs(d1-d2)<=epsilon) return 0;

        return d1.CompareTo(d2);
    }
}

现在这个 IComparer 关系显然是不可传递的。 (如果 a ~ b 和 b ~ c 那么 a ~ c)

使用 epsilon== 0.6 :

  • 比较(1, 1.5) == 0
  • 比较(1.5, 2) == 0
  • 比较(1, 2) == -1

如果在 OrderBy 查询中使用此 IComparer 会发生什么情况,如下所示:

List<Item> itemlist;
itemList = itemlist.OrderBy(item=>item.X, new EpsilonComparer(0.352))
                   .ThenBy (item=>item.Y, new EpsilonComparer(1.743)).ToList();

排序是否会像人们预期的那样首先按 X 排序列表,然后按 Y 排序,同时将大致相等的值视为完全相等?
在某些情况下它会爆炸吗?
还是这整类定义不明确?

使用没有传递性的 IComparer 究竟会产生什么后果?

(我知道这很可能是 c# 语言的未定义行为。我仍然对答案非常感兴趣。)

是否有其他方法可以实现这种排序行为?
(除了对值进行四舍五入外,当两个接近的 double 一个向上舍入另一个向下时会引入伪影)

此问题中的代码的在线文件可用here :

最佳答案

问题是第一个排序级别(在 X 上)可能已经导致不同的顺序。想象一下,所有项目都在彼此的一个 epsilon 之内。然后所有排序顺序都与您的比较器一致,因为它总是返回 0。排序算法可以抛硬币并仍然提供“正确”答案。没用。

如果第一级是任意排序的,则不能指望第二级排序起作用。

当然,所有这些讨论都没有实际意义,因为您违反了排序 API 的先决条件。即使它碰巧有效,您也不能确定它是否适用于 a) 所有数据 b) 所有 future 版本的 .NET。

你怎样才能实现你的目标?您的问题定义不明确,因为许多解决方案都是可能的。我得到了您想实现的目标,但是您当前对问题的定义是不可能的。

我建议:按 X(不带 epsilon)对所有项目进行排序。然后,从左到右遍历排序的项目并将项目合并到最多一个 epsilon 宽的组中。这会为您提供 X 值至多相差 epsilon 的项目组。

然后您可以使用组编号作为第一个排序级别。它只是一个简单的整数,因此对其进行排序没有问题。对于 Y 字段,您可以使用不带 epsilon 的普通比较器(或重复相同的技巧)。

关于c# - 带有非传递 IComparer 的 OrderBy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20363810/

有关c# - 带有非传递 IComparer 的 OrderBy的更多相关文章

  1. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  2. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  3. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  4. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  5. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  6. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  7. ruby-on-rails - 带有 Zeus 的 RSpec 3.1,我应该在 spec_helper 中要求 'rspec/rails' 吗? - 2

    使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做

  8. ruby - 如何将 Puma::Configuration 传递给 Sinatra? - 2

    这是我的网络应用:classFront我是这样开始的(请不要建议使用Rack):Front.start!这是我的Puma配置对象,我不知道如何传递给它:require'puma/configuration'Puma::Configuration.new({log_requests:true,debug:true})说真的,怎么样? 最佳答案 配置与您运行的方式紧密相关puma服务器。运行的标准方式puma-pumaCLI命令。为了配置puma配置文件config/puma.rb或config/puma/.rb应该提供(参见examp

  9. Ruby:如何使用带有散列的 'send' 方法调用方法? - 2

    假设我有一个类A,里面有一些方法。假设stringmethodName是这些方法之一,我已经知道我想给它什么参数。它们在散列中{'param1'=>value1,'param2'=>value2}所以我有:params={'param1'=>value1,'param2'=>value2}a=A.new()a.send(methodName,value1,value2)#callmethodnamewithbothparams我希望能够通过传递我的哈希以某种方式调用该方法。这可能吗? 最佳答案 确保methodName是一个符号,而

  10. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

随机推荐