我无法想象从一个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数组在sTitle和sRelativePath成员中是唯一的,其他成员可以是重复的
编辑:
感谢所有的答案,但这个应用程序是"可移植的"我的意思是我只需要.exe文件,我不想添加其他文件,如引用*.dll所以请不要外部引用此应用程序旨在用于随身碟
所有数据都来自*.ini文件,我所做的是:(伪代码)
ReadFile()
FillDataFromFileInAppInfoArray()
DeleteDuplicates()
FillListViewControl()
Run Code Online (Sandbox Code Playgroud)
当我想将这些数据保存到文件中时,我有以下选项:
EDIT2:
非常感谢:Jon Skeet,Michael Hays感谢您的时间!
首先,请不要使用可变结构.他们在各方面都是个坏主意.
其次,请不要使用公共领域.字段应该是实现细节 - 使用属性.
第三,我并不清楚这应该是一个结构.它看起来相当大,而不是特别"单一价值".
第四,请遵循.NET命名约定,以便您的代码适合用.NET编写的所有其余代码.
第五,您不能从数组中删除项目,因为数组是使用固定大小创建的......但您可以创建仅包含唯一元素的新数组.
LINQ到对象可以让你做到这一点已经在使用GroupBy如图阿尔宾,但稍微整洁(在我看来)的方法是使用DistinctBy从MoreLINQ:
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.是的,它涉及构建更多的对象,但我更喜欢清晰度而不是效率,直到基准测试证明实际需要更高效的代码.