从struct数组中删除重复项

ttt*_*ony 1 .net c# c#-4.0

我无法想象从一个struct数组中删除duplicates条目

我有这个结构:

public struct stAppInfo
{
    public string sTitle;
    public string sRelativePath;
    public string sCmdLine;
    public bool bFindInstalled;
    public string sFindTitle;
    public string sFindVersion;
    public bool bChecked;
}
Run Code Online (Sandbox Code Playgroud)

我已经改变了stAppInfo结构类在这里感谢乔恩斯基特

代码是这样的:(简短版)

stAppInfo[] appInfo = new stAppInfo[listView1.Items.Count];

int i = 0;
foreach (ListViewItem item in listView1.Items)
{
    appInfo[i].sTitle = item.Text;
    appInfo[i].sRelativePath = item.SubItems[1].Text;
    appInfo[i].sCmdLine = item.SubItems[2].Text;
    appInfo[i].bFindInstalled = (item.SubItems[3].Text.Equals("Sí")) ? true : false;
    appInfo[i].sFindTitle = item.SubItems[4].Text;
    appInfo[i].sFindVersion = item.SubItems[5].Text;
    appInfo[i].bChecked = (item.SubItems[6].Text.Equals("Sí")) ? true : false;
    i++;
}
Run Code Online (Sandbox Code Playgroud)

我需要appInfo数组在sTitlesRelativePath成员中是唯一的,其他成员可以是重复的

编辑:

感谢所有的答案,但这个应用程序是"可移植的"我的意思是我只需要.exe文件,我不想添加其他文件,如引用*.dll所以请不要外部引用此应用程序旨在用于随身碟

所有数据都来自*.ini文件,我所做的是:(伪代码)

ReadFile()
FillDataFromFileInAppInfoArray()
DeleteDuplicates()
FillListViewControl()
Run Code Online (Sandbox Code Playgroud)

当我想将这些数据保存到文件中时,我有以下选项:

  1. 使用ListView数据
  2. 使用appInfo数组(这更快?)
  3. 任何其他?

EDIT2:

非常感谢:Jon Skeet,Michael Hays感谢您的时间!

Jon*_*eet 9

首先,不要使用可变结构.他们在各方面都是个坏主意.

其次,不要使用公共领域.字段应该是实现细节 - 使用属性.

第三,我并不清楚这应该是一个结构.它看起来相当大,而不是特别"单一价值".

第四,请遵循.NET命名约定,以便您的代码适合用.NET编写的所有其余代码.

第五,您不能从数组中删除项目,因为数组是使用固定大小创建的......但您可以创建仅包含唯一元素的新数组.

LINQ到对象可以让你做到这一点已经在使用GroupBy如图阿尔宾,但稍微整洁(在我看来)的方法是使用DistinctByMoreLINQ:

var unique = appInfo.DistinctBy(x => new { x.sTitle, x.sRelativePath })
                    .ToArray();
Run Code Online (Sandbox Code Playgroud)

GroupBy在我看来,这通常比效率更高,也更优雅.

就个人而言,我通常更喜欢使用List<T>数组,但上面会为你创建一个数组.

请注意,使用此代码仍然可以有两个具有相同标题的项目,并且仍然可以有两个具有相同相对路径的项目 - 不能有两个具有相同相对路径标题的项目.如果存在重复项,DistinctBy则始终从输入序列中生成第一个此类项.

编辑:只是为了满足迈克尔,你实际上并不需要创建一个数组下手,或创建一个数组之后,如果你不需要它:

var query = listView1.Items
                     .Cast<ListViewItem>()
                     .Select(item => new stAppInfo
                             {
                                 sTitle = item.Text,
                                 sRelativePath = item.SubItems[1].Text,
                                 bFindInstalled = item.SubItems[3].Text == "Sí",
                                 sFindTitle = item.SubItems[4].Text,
                                 sFindVersion = item.SubItems[5].Text,
                                 bChecked = item.SubItems[6].Text == "Sí"
                             })
                     .DistinctBy(x => new { x.sTitle, x.sRelativePath });
Run Code Online (Sandbox Code Playgroud)

这将给你一个IEnumerable<appInfo>懒惰的流.请注意,如果您遍历一次以上,但是,它遍历listView1.Items了相同的次数,在执行每一次相同的独特性比较.

我比Michael更喜欢这种方法,因为它使得"distinct by"列在语义上非常清晰,并且删除了用于从a中提取这些列的代码的重复ListViewItem.是的,它涉及构建更多的对象,但我更喜欢清晰度而不是效率,直到基准测试证明实际需要更高效的代码.