Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >比较两个节点列表和完全匹配

比较两个节点列表和完全匹配
EN

Stack Overflow用户
提问于 2022-09-06 19:34:39
回答 2查看 50关注 0票数 2

我创建了两个对象列表,但不能执行总计匹配值,即

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var inputNodes = new List<nodes>()
            {
                new node() { nodeName= "D100", DataLength = 1 },
                new node() { nodeName= "D101", DataLength = 1 },
                new node() { nodeName= "D102", DataLength = 1 },
                new node() { nodeName= "D103", DataLength = 1 },
                new node() { nodeName= "D104", DataLength = 1 },
                new node() { nodeName= "D105", DataLength = 1 },
                new node() { nodeName = "D106", DataLength = 1 }
            };

        var inputNodes2 = new List<nodes>()
        {
            new node() { nodeName= "D100", DataLength = 1 },
            new node() { nodeName= "D101", DataLength = 1 },
            new node() { nodeName= "D102", DataLength = 1 },
            new node() { nodeName= "D103", DataLength = 1 },
            new node() { nodeName= "D104", DataLength = 1 },
            new node() { nodeName= "D105", DataLength = 1 },
            new node() { nodeName= "D106", DataLength = 1 }
        };

我尝试使用check,var isEqual = inputNodes.SequenceEqual(inputNodes2),它返回false,我不想使用循环或list.select函数,对此有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-08 03:18:02

在我看来,你似乎不熟悉平等的概念,以及如何将平等的定义转变为你的定义。因此,我将解释默认等式,以及如何编写一个包含您的平等思想的等式比较器。

默认情况下,对象的相等是引用相等:如果两个对象引用相同的对象,则它们是相等的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Node A = new Node {...}
Node X = A;
Node Y = A;

对象X和Y指同一个对象,因此:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Assert(X == Y)
IEqualityComparer<Node> nodeComparer = EqualityComparer<Node>.Default;
Assert(nodeComparer.Equals(x, y));

但是,在您的示例中,inputNodes[0]inputNodes2[0]不引用同一个对象。因此,它们不是相等的节点,因此SequenceEqual将返回false。

你不想使用标准的平等比较,你想要一个特殊的比较。根据您的定义,如果节点的属性相等,则两个节点是相等的。这个平等的定义被称为“价值平等”,与“参考平等”形成对比。

因为您不想使用默认的引用等式,所以您必须自己编写等式比较器。最简单的方法是从EqualityComparer派生一个类。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class NodeComparer : EqualityComparer<Node>
{
    public static IEqualityComparer<Node> ValueComparer {get} = new NodeComparer();

    public override bool Equals(Node x, Node y) {... TODO: implement}
    public override int GetHashCode(node x) {... TODO: implement}
}

使用情况如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
IEnumerable<Node> inputNodes1 = ...
IEnumerable<Node> inputNodes2 = ...

IEqualityComparer<Node> nodeComparer = NodeComparer.ValueComparer;
bool equalInputNodes = inputNodes1.SequenceEqual(inputNodes2, nodeComparer);

等于

定义依赖于--您的平等定义。你可以使用你需要的任何定义。在您的例子中,您选择了一个简单的“按值进行比较”:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public override bool Equals(Node x, Node y)
{
    // The following statements are almost always the same for every equality
    if (x == null) return y == null;               // true if both null
    if (y == null) return false;                   // because x not null
    if (Object.ReferenceEquals(x, y)) return true; // because same object
    if (x.GetType() != y.GetType()) return false;  // different types

在某些情况下,这些说法可能有所不同。例如,如果您想要创建一个字符串比较器,其中空字符串等于空字符串:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
string x = null;
string y = String.Empty;
IEqualityComparer<string> stringComparer = MyStringComparer.EmptyEqualsNull;
Assert(stringComparer.Equals(x, y));

或者,如果你认为教师是人,而不是在某些情况下,你可能希望当你比较一个老师和一个人,你可能不想检查类型。

但总的来说,大多数比较器将使用这四条初始行。

继续你的平等:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
return x.NodeName == y.NodeName
    && x.DataLength == y.DataLength;

为未来做好准备,考虑以下几点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static readonly IEqualityComparer<string> nodeNameComparer = StringComparer.Default;

在你的平等方法中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
return nodeNameComparer.Equals(x.NodeName, y.NodeName)
    && x.DataLength == y.DataLength;

因此,如果将来要进行不区分大小写的字符串比较,只需更改nodeNameComparer的静态声明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static readonly IEqualityComparer<string> nodeNameComparer = StringComparer.OrdinalIgnoreCase;

GetHashCode

GetHashCode的目的是创建一个快速方法来分离大多数不平等的对象。如果节点有200个属性,并且您知道,如果它们的属性Id值相等,那么很可能所有其他元素都是相等的,这是非常有用的。

请注意,我使用“非常可能”。如果X有与Y相同的哈希码,则不能保证X将等于Y,但您可以确定:

如果X与Y有不同的哈希码,那么它们就不相等。

GetHashCode的唯一要求是,如果X等于Y,那么MyComparer.GetHashCode(X)等于MyComparer.GetHashCode(Y);

如果X不等于Y,那么您就不知道它们的哈希码是否会有所不同,不过如果是这样的话会更好,因为代码会更高效。

GetHashcode应该是快速的,它不需要检查所有的东西,如果它分离了大多数元素,它可能会很方便,但是它不需要是一个完全相等的检查。

这个怎么样?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public override int GetHashCode(Node x)
{
    if (x == null) return 874283;      // just a number

    // for HashCode only use the NodeName:
    return x.NodeName.GetHashCode();
}

或者,如果在方法中对NodeName使用字符串比较器等于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static readonly IEqualityComparer<string> nodeNameComparer = StringComparer.OrdinalIgnoreCase;

// this comparer is used in Equals

public override int GetHashCode(Node x)
{
    if (x == null) return 874283;      // just a number
    return nodenameComparer.GetHashCode(x.NodeName);
}

因此,如果以后将节点名的比较方法更改为CurrentCulture,那么等于和GetHashCode都将使用适当的比较器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Node a = new Node {nodeName= "X", DataLength = 1 };
Node b = new Node {nodeName= "X", DataLength = 1 };
Node c = new Node {nodeName= "X", DataLength = 2 };
Node d = new Node {nodeName= "Y", DataLength = 1 };

很容易看出,b等于A.c和d与a是不同的。

虽然c是不同的,但比较器将返回与a相同的哈希码。因此,GetHashCode不足以实现完全相等,但是一个好的GetHashCode将分离大多数不同的对象。

票数 1
EN

Stack Overflow用户

发布于 2022-09-06 20:00:24

使用如下所示的IEqualityComparer

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class NodeComparer : IEqualityComparer<node>
{
    public bool Equals(node? x, node? y)
    {
        if(x == null && y == null){
            return true;
        }

        if(x == null || y == null)
        {
            return false;
        }

        return string.Equals(x.nodeName, y.nodeName) && x.DataLength == y.DataLength;
    }

    public int GetHashCode([DisallowNull] node obj)
    {
        return obj.nodeName.GetHashCode() * obj.DataLength.GetHashCode();
    }
}

然后在SequenceEquals中使用它

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inputNodes.SequenceEqual(inputNodes2, new NodeComparer());
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73629824

复制
相关文章
在MacOs上用Docker开发
该文章介绍如何使用Docker在Mac上构建和运行Node.js应用程序。首先,介绍了Docker的基本概念和优势,然后详细说明了在Mac上使用Docker的开发流程。包括拉取Docker镜像、运行容器、管理容器和容器路径等。最后,探讨了Docker在软件开发和部署中的重要性,以及Docker在Mac上的实际应用场景。
花落花飞去
2017/12/27
4.1K0
在macOS上安装&配置PostgreSQL
Homebrew以及dmg安装包安装都可以,不过Homebrew跟dmg包图形化安装还是有些区别,根据自己习惯任选其一即可,不过为了方便理解后续的操作,还是简单介绍下两种安装方式的区别
KenTalk
2023/04/07
12.8K0
在macOS上安装&配置PostgreSQL
在MacOS上安装配置Mongodb
MongoDB 去年 10 月份宣布将开源 License 从 GNU AGPLv3 切换到 Server Side Public License(SSPL),之后遭到了来自开源社区的抵制。
雪梦科技
2020/05/11
1.7K0
在MacOS上源码安装OpenCV-4.0.0
OpenCV-4.0.0已经放出来一阵日子了,很有新功能新特性值得尝试,由于MacOS上的brewhome包中编译好的OpenCV版本只有3.4.3,为了在MacOS上安装最新的OpenCV,只好走源码编译这条路了。
老潘
2023/10/19
4030
在MacOS上源码安装OpenCV-4.0.0
在ESXi上安装macos虚拟机
再一想,是AIX什么时候可以运行在ESXi上?也许永远没有机会了,毕竟已经进入云计算大数据时代了。
boypoo
2020/02/14
8.2K1
用 pyenv 在 MacOS 上创建虚拟环境
创建名为 my-310-python 的虚拟目录,并且其中加载 Python 3.10.0 。
老齐
2022/03/31
1.2K0
在Xcode8上安装插件之后闪退
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/53197701
用户1451823
2018/09/13
7400
在macOS上安装配置golang开发环境
通过编辑器打开 .bashrc 或者 .zshrc,将以下配置贴到文件最后,并保存。
雪梦科技
2020/05/11
1.6K0
Mac OS X安装OpenCV并配置到Xcode和Eclipse上
1).首先下载opencv for mac安装源文件,http://opencv.org/downloads.html,解压缩
用户8704835
2021/06/07
7000
在VirtualBox上安装Android-X86
对于Android开发来说,尤其是新手(没错,我自己就是noob?),有很多种开发调试的方案。比如Genymotion+VirtualBox搭配方案(在我的笔记本上这种方案性能最低,可能因配置而异)、
Bess Croft
2020/04/02
6.1K0
最新版MySQL在MacOS上的安装与使用!
我们本文将采用最常规的方式,也就是安装包的方式进行安装,这也是我推荐给新手的安装方式,因为这种安装方式更直观更可控一些,比如对 MySQL 版本的选择和密码配置等,那接下来我们就直接开始吧。
磊哥
2020/10/27
2K0
最新版MySQL在MacOS上的安装与使用!
在Proxmox 6.2 上安装 macOS Big Sur 虚拟机
问题关键字:macOS,macOS Big Sur,macOS Big Sur 虚拟机安装
欧巴云
2021/08/04
4.1K0
用 Flatpak 在 Linux 上安装应用
计算机应用由许多小文件组成,它们被链接在一起以执行一系列的任务。因为它们以“应用”的形式出现,在菜单或桌面上有彩色的图标,我们大多数人认为应用是一个单一的、几乎是有形的东西。在某种程度上,这样想是令人欣慰的,因为它们感觉是可以管理的。如果一个应用实际上是散落在你的计算机上的数百个小库和资源文件的组合,那么应用在哪里?撇开存在危机不谈,当一个应用需要一个版本的库,而另一个应用需要一个不同的版本时,会发生什么?
用户8965210
2022/01/04
1.7K0
在CentOS上用Caddy安装WordPress
WordPress是一个以PHP和MySQL为平台的自由开源的博客软件和内容管理系统。WordPress具有插件架构和模板系统。Alexa排行前100万的网站中有超过16.7%的网站使用WordPress。到了2011年8月,约22%的新网站采用了WordPress。WordPress是目前因特网上最流行的博客系统。
独钓寒江雪_Ly
2018/07/30
4.9K1
在 Mac OS X 上安装和配置 Wine
Windows 上也有很多优秀的工具软件是 Mac 上没有的, 装虚拟机的话太浪费, 而且效率不高, 幸好可以通过 Wine 来运行 Windows 程序, 通过 HomeBrew 使得 Wine 的安装非常容易, 通过 WineTricks 来配置 Wine 也没有多大困难, 下面是我在 Mac 上安装和配置 Wine 的纪录。
beginor
2020/08/10
15K1
在Mac OS X上安装PHP7
Mac用户可以选择二进制或源安装。实际上,您的OS X可能预装了Apache和PHP。这可能是一个相当旧的版本,它可能缺少许多不太常见的扩展。
用户9042463
2021/09/29
1.4K0
在CentOS 6上安装Discuz! X2.5
简明过程 1. 参考 http://www.linuxidc.com/Linux/2014-09/107373.htm 但是,实际上可以不用这么复杂。而且由于nginx配置php比较费劲,最后用apache解决了。
星哥玩云
2022/07/03
7000
在CentOS 6上安装Discuz! X2.5
macOS 用 Docker 安装 gogsDockergogs配置
Docker https://store.docker.com/editions/community/docker-ce-desktop-mac gogs https://github.com/gogits/gogs/tree/master/docker $ docker -v # 查看版本 Docker version 18.03.1-ce, build 9ee9f40 $ docker pull gogs/gogs # Pull image from Docker Hub. $ [sudo] mkd
iOSDevLog
2018/07/04
8520
在 MacOS 上读取 Btrfs 分区文件
Btrfs 文件系统相较于 Ext4 ,是一种更年轻的文件系统,具有更多可玩的特征,比如支持快照、子卷、校验和自检、软 RAID 甚至透明压缩等。
陈少文
2021/12/22
4.6K0
点击加载更多

相似问题

从文件中提取单词

40

从文件中提取单词

30

从文件中提取单词

51

从日志文件中提取特定的单词(不是关键字)

20

从日志文件中提取日志时间

35
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文