首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >比较两个节点列表和完全匹配

比较两个节点列表和完全匹配
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

复制
相关文章
c++禁止隐式转换_无法将int隐式转换为类
那么如何阻止它呢? C++ 标准有一条规定: “Implicit conversions will be performed […] if the parameter type contains no template-parameters that participate in template argument deduction” (ISO/IEC 14882:1998, section 14.8.1.4). 也就是说,既在模板参数列表中,又在函数参数列表中的类型不会隐式转换。也就是:
全栈程序员站长
2022/11/10
1.2K0
解决php无法将string转换为json的办法
背景:最近在开发小程序(替客户做的),一个水印小程序,通过接口实现了去掉水印,原理很简单,但是由于目标解析的地址域名太多,用了域名通配后也是出现不在合法域名中的错误,于是只能用自己的服务器来进行一个踏板,所以当数据回调后需要清洗数据出来给小程序用,在这里就出现了问题:
德宏大魔王
2023/08/08
1500
解决php无法将string转换为json的办法
无法转换为内部表示
系统查询表记录时出现“java.sql.SQLException: 无法转换为内部表示”异常,抛出的异常信息如下:
程序新视界
2022/11/30
6790
Unity-资源打包-AssetBundle
读取AB包 1.直接记载一个单独的物体(无依赖) 通过AssetBundle的LoadFromFile方法获取AB包,在通过LoadAsset的泛型方法获得GameObject
祝你万事顺利
2019/05/29
2.8K0
无法重新布局的问题
调用的是Activity的getLayoutInflater 这句代码原本是没有什么问题的,但是在Fragment中使用就有问题了。
用户10521372
2023/04/21
4280
使用dx将class转dex总结
dx工具是一种用来转换Java class成为DEX格式的工具。多个类被包含在一个dex文件之中。各个类中重复的字符串和其他常数只在DEX中存放一次,以节省空间。Java字节码(bytecode)被转换成Dalvik虚拟机所使用的替代指令集。一个未压缩dex文件通常稍小于一个已经压缩的.jar档(摘自维基百科)。
静默加载
2020/05/29
1.6K0
unity3d 资源打包加密
string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
py3study
2020/01/08
1.2K0
简单 Unity3D 安卓游戏逆向思路
起因是个人很喜欢玩 google play 上的一些数字类型(角色攻击是线性增长,怪物指数变强,到后期越打不过,通过重生增强属性变强)的小游戏。但是这种游戏仍旧存在一定缺陷,前期资源不多,玩的太慢、玩的时间长了,就感觉没意思,就不想玩了,所以在玩到游戏中期的时候,往往都会去网上搜索XXX破解版/内购版,快速进入后期然后放弃这款游戏。
Seebug漏洞平台
2019/02/26
4.8K1
关于flutter打包无法上传的问题
在Android端,当minSdkVersion为24经flutter build apk打包出来的apk在大部分应用市场上都存在签名问题,无法正常上传apk。解决的方法是,使用Android Studio打开Android进行原生打包,即使用 【Build】->【Generate Signed Bundle/APK】->【选择APK】->【填写签名信息】->【Signature Versions只勾选V1】的方式进行签名。
xiangzhihong
2022/11/30
1.1K0
无法将类型“System.Collections.Generic.IEnumerable<EmailSystem.Model.TemplateInfo>”隐式转换为“System.Collection
List<Model.Template> templateList = templateBLL.RecommendTemplateByOrder(modelEbay);        List<Model.TemplateInfo> recommandlist = templateList.Select(m => new Model.TemplateInfo                 {                     AccountId = m.AccountID,            
跟着阿笨一起玩NET
2018/09/19
1.6K0
将tensor转换为图像_tensor转int
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/07
11.4K0
Idea 中图片资源无法加载问题
今天在看一个 Java 的小游戏时,遇到项目图片资源无法加载的问题,运行显示界面如图
攻城狮杰森
2022/06/03
2.9K0
Idea 中图片资源无法加载问题
【Android 热修复】热修复原理 ( 多 Dex 打包机制 | 多 Dex 支持 | Dex 分包设置 | 开发和产品风格设置 | 源码资源 )
在 【Android 热修复】热修复原理 ( 类加载机制 | PathClassLoader 加载 Dex 机制 | PathDexList 查找 Class 机制 | 类查找的顺序机制 )三、 类查找的顺序机制 博客章节有讲解到 , Android 类加载时 , 必须进行分包操作 , 必须有
韩曙亮
2023/03/29
9650
【Android 热修复】热修复原理 ( 多 Dex 打包机制 | 多 Dex 支持 | Dex 分包设置 | 开发和产品风格设置 | 源码资源 )
pyinstaller打包pyqt5程序无法运行
转载自:https://www.cnblogs.com/boliu/p/7574804.html
渔父歌
2019/02/28
2K0
自动构建Unity3D项目到二进制程序
Unity3D 是一个用于创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的综合型创作工具。其编辑器运行在Windows和Mac OS X下,可发布游戏至Windows、Wii、OSX或iOS平台。他的持续集成方法主要是通过调用 BuildPipline.BuildPlayer() 方法来实现直接生成Windows/MacOS下可运行的程序,或生成Android/iOS项目,再通过脚本进行编译打包生成apk/ipa。利用图形化界面Jenkis来方便用户使用。
海哥@开发
2022/04/04
8970
Unity使用AssetImporter整理资源对其进行打包
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
bering
2019/12/02
2.8K0
Unity3d热更新(二):资源打包As
2.在Assets目录下创建Scenes文件夹,创建场景scene1.unity。
py3study
2020/01/11
9130
解决webpack打包静态资源(样式)无法添加厂商前缀-webkit -moz -ms -o的问题
可以设置以下browserlist,现在webpack默认你的项目支持高版本浏览器,我们可以将支持的浏览器覆盖的全面一点就出来前缀了
砖业洋__
2023/05/06
2600
解决webpack打包静态资源(样式)无法添加厂商前缀-webkit -moz -ms -o的问题
如何帮助企业将原始长链接转换为短链接?
小码短链接是一款短链接工具,帮助企业将原始长链接转换为短链接,并可以支持短链接访问统计,可以设置自定义域名的短链接,微信朋友圈分享设置,抖音平台分享设置等功能。
用户9934601
2022/08/30
1.7K0
点击加载更多

相似问题

Unity Android无法重新打包资源

132

Unity Android build -无法重新打包资源

10

Unity 5-无法重新打包资源

15

Unity3d (无法重新打包资源。)

12

Unity Android构建错误:无法重新打包资源

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

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

洞察 腾讯核心技术

剖析业界实践案例

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