如何在C#的List <struct>中查找条目是否存在?

时间:2017-08-07 11:40:02

标签: c# winforms

我有文本框,我将其输入设置为结构,如下所示。

public struct mappingData
{
    public string a;
    public string b;
    public int c;
}
mappingData mappingFileData;
public List<mappingData> mappingDatabase = new List<mappingData>();`

单击按钮后,我将其存储到List

private void btnAddMapData_Click(object sender, EventArgs e)
{
mappingFileData.a = addressPrefixMbDataType[cbMbDataType.SelectedIndex];
mappingFileData.b = addressPrefixMbValue[cbMbValue.SelectedIndex];
mappingFileData.c = Int32.Parse(tbAddress.Text);

// Add new entry to the linked list each time when 'btnAddMapData' is clicked 
mappingDatabase.Add(mappingFileData);
}

现在我的数据库可以跟随

  

a,x,1

     

a,x,2

     

b,x,1

     

b,x,2

但它不应该如下所示

  

a,x, 1

     

a,x, 1 &gt;重复的beacause已经“1”以前可用

     

b,x, 2

     

b,x, 2 &gt;重复的beacause已经“2”以前可用

     

b,x, 1 &gt;不重复,因为第一个参数是不同的'b'所以“a”和“b”都可以保持1,因为两者都不同,但如果列表中有两个“a”那么应该只有一个“1”

有人,请建议我一个想法

3 个答案:

答案 0 :(得分:2)

如果你想要一种万无一失的方法来检查重复项,你必须先修改你的结构来覆盖==运算符和相关的方法:

public struct mappingData
{
    public string mbDataType;
    public string mbValue;
    public string daliAddrType;
    public int mbAddress;
    public string daliCmdNo;
    public int daliDevId;

    public override bool Equals(Object obj)
    {
        return obj is mappingData && this == (mappingData)obj;
    }

    public override int GetHashCode()
    {
        return (mbDataType.GetHashCode() + mbValue.GetHashCode() + daliAddrType.GetHashCode() + daliCmdNo.GetHashCode()) * mbAddress * 807403 * daliDevId;
    }

    public static bool operator ==(mappingData x, mappingData y)
    {
        return x.mbDataType == y.mbDataType && x.mbValue == y.mbValue && x.daliAddrType == y.daliAddrType && x.mbAddress == y.mbAddress && x.daliCmdNo == y.daliCmdNo && x.daliDevId == y.daliDevId;
    }

    public static bool operator !=(mappingData x, mappingData y)
    {
        return !(x == y);
    }
}

现在,您可以使用LINQ或类似方法并比较mappingData

的相同实例
if (!mappingDatabase.Contains(mappingFileData))
{
    mappingDatabase.Add(mappingFileData);
}

修改

如果想要检查相同的mbAddressmbDataType,那么您根本不需要修改结构。你可以马上做到这一点:

if (!mappingDatabase.Any(m => m.mbAddress == mappingFileData.mbAddress && m.mbDataType == mappingFileData.mbDataType))
{
    mappingDatabase.Add(mappingFileData);
}

答案 1 :(得分:2)

如果使用struct,则默认实现会考虑所有字段以生成结果哈希码。因此,只需将结构放入HashSet<>即可解决问题:

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var items = Enumerable.Range(1, 100)
                              .Select(value => value % 10)
                              .Select(value => new mappingData{ a = "a" + value, b = "b" + value, c = value });
        var hashSet = new HashSet<mappingData>(items);

        // Outputs only first ten elements
        foreach(var item in hashSet)
        {
            Console.WriteLine(item);
        }

    }

    public struct mappingData
    {
        public string a;
        public string b;
        public int c;

        public override string ToString()
        {
            return $"{a} {b} {c}";
        }
    }
}

答案 2 :(得分:1)

List有几种扩展方法可以帮助您查找列表中的数据。在您的情况下,我建议使用Count方法。它也适用于结构。

int found = mappingDatabase.Count(delegate (mappingData obj) { return obj.a.Equals("a") && obj.b.Equals("x"); });

然后,您可以设置自己的搜索规则,并确定它是否重复。

在调用Count之前,不要忘记检查mappingDatabase是否为null。