C# 如何从多个列表中选择不同且有序的数据到通用列表中?
我有几个通用列表,其中包含一些共享和唯一的数据。它们包含相同类的数据,但使用不同的参数(单位)填充。所以所有的通用列表都属于这种类型:C# 如何从多个列表中选择不同且有序的数据到通用列表中?,c#,linq,generic-list,C#,Linq,Generic List,我有几个通用列表,其中包含一些共享和唯一的数据。它们包含相同类的数据,但使用不同的参数(单位)填充。所以所有的通用列表都属于这种类型:List 我想对这些通用列表做的是从中提取它们所包含的不同数据的子集,然后对合并后的列表进行排序 更具体地说,要查询的列表具有以下结构: public class PriceVarianceData { public String Unit { get; set; } public String ShortName { get; set; }
List
我想对这些通用列表做的是从中提取它们所包含的不同数据的子集,然后对合并后的列表进行排序
更具体地说,要查询的列表具有以下结构:
public class PriceVarianceData
{
public String Unit { get; set; }
public String ShortName { get; set; }
public String ItemCode { get; set; }
public String Description { get; set; }
public String PriceWeek { get; set; }
public String Week { get; set; }
public String Price { get; set; }
public String Variance { get; set; }
public String VarianceAverage { get; set; }
public int RegionOrder { get; set; }
public int ContractPrice { get; set; }
}
public class PriceVarianceSupersetDisplayData
{
public String ShortName { get; set; }
public String ItemCode { get; set; }
public String Description { get; set; }
}
…我要将数据提取到的通用列表具有以下结构:
public class PriceVarianceData
{
public String Unit { get; set; }
public String ShortName { get; set; }
public String ItemCode { get; set; }
public String Description { get; set; }
public String PriceWeek { get; set; }
public String Week { get; set; }
public String Price { get; set; }
public String Variance { get; set; }
public String VarianceAverage { get; set; }
public int RegionOrder { get; set; }
public int ContractPrice { get; set; }
}
public class PriceVarianceSupersetDisplayData
{
public String ShortName { get; set; }
public String ItemCode { get; set; }
public String Description { get; set; }
}
这些单位将有一些相同的ShortName+ItemCode+描述值,我只想要这些值的唯一组合-ShortName+ItemCode+描述不应该有重复项,但是如果它们在任何值上不同,它们将被视为唯一/不同。因此,排序后提取的数据应如下所示:
SHORTNAME ITEMCODE DESCRIPTION
--------- -------- -----------
Fakeroo 001 Stratoblaster
Fender 001 Stratocaster
Gibson 001 335
Gibson 001 SG
Fender 002 Telecaster
Gibson 002 Les Paul
Carvin 003 Knife
Carvin 003 L6S
我(想我)知道我在这里需要的是LINQ查询;在伪代码中,类似于:
List<PriceVarianceSupersetDisplayData> displayDataAmalgamated = select distinct ShortName, ItemCode, Description from craftworksPVDList, chophousePVDList, gordonbierschPVDList, oldchicagoPVDList, oldchifranchisePVDList, rockbottomPVDList order by ItemCode then by ShortName, then by Description
List displaydatamergalized=从craftworksPVDList、Chophouse PVDList、gordonbierschPVDList、oldchicagoPVDList、OldChi PVDList、rockbottomPVDList中选择不同的ShortName、ItemCode、Description,按项目代码、ShortName、Description排序
…但不知道如何将伪代码转换成真正的LINQ
更新
user3185569和Zoran Horvat的答案的组合似乎有效,但我显然没有得到明确的值。我的第一个线索是,最终通用列表中的条目数量似乎过高
然后我查看了列表中的前两个条目,它们(或至少看起来)是相同的:
这是我正在使用的代码;如前所述,它是前两个答案的组合:
private List<PriceVarianceSupersetDisplayData> GetSharedDisplayDataForAll()
{
Func<PriceVarianceData, PriceVarianceSupersetDisplayData> selector =
(p => new PriceVarianceSupersetDisplayData()
{
ShortName = p.ShortName,
ItemCode = p.ItemCode,
Description = p.Description
});
List<PriceVarianceSupersetDisplayData> displayDataAmalgamated =
craftworksPVDList.Concat(chophousePVDList)
.Concat(chophousePVDList)
.Concat(gordonbierschPVDList)
.Concat(oldchicagoPVDList)
.Concat(oldchifranchisePVDList)
.Concat(rockbottomPVDList).Select(selector)
.Distinct()
.OrderBy(x => x.ItemCode)
.ThenBy(x => x.ShortName)
.ThenBy(x => x.Description).ToList();
return displayDataAmalgamated;
}
private List GetSharedDisplayDataForAll()
{
函数选择器=
(p=>新价格差异SuperSetDisplayData()
{
ShortName=p.ShortName,
ItemCode=p.ItemCode,
描述=p.描述
});
列表显示数据合并=
工艺列表。Concat(chophousePVDList)
.Concat(印章列表)
.Concat(GordonbierschList)
康卡特先生(旧芝加哥)
.Concat(旧目录)
.Concat(列表)。选择(选择器)
.Distinct()
.OrderBy(x=>x.ItemCode)
.ThenBy(x=>x.ShortName)
.ThenBy(x=>x.Description).ToList();
返回数据合并;
}
为什么Distinct()返回重复的值?如果您希望用所有部分列表中的不同数据构建另一个列表,那么您可以通过使用Concat LINQ方法将它们连接在一起,然后最终使用Distinct LINQ方法来轻松实现:
list1.Concat(list2).Concat(list3)...Concat(listN).Distinct();
这假设类是值类型。因为您使用的是非常简单的类,所以我建议您在这些类中实现值类型语义,然后这种列表操作将变得微不足道
添加值类型语义意味着覆盖GetHashCode、Equals、add运算符==和运算符!=最好用它自己的等式(T)实现IEnumerable。如我所说,完成所有这些之后,列表操作将变得微不足道
可以在最后添加数据排序,如:
list1
.Concat(list2)
.Concat(list3)
...
.Concat(listN)
.Distinct()
.OrderBy(x => x.ItemCode)
.ThenBy(x => x.ShortName)
.ThenBy(x => x.Description);
如果您希望构造另一个仅包含来自所有部分列表的不同数据的列表,则可以通过使用Concat LINQ方法将它们连接在一起,然后最终使用distinct LINQ方法来轻松完成:
list1.Concat(list2).Concat(list3)...Concat(listN).Distinct();
这假设类是值类型。因为您使用的是非常简单的类,所以我建议您在这些类中实现值类型语义,然后这种列表操作将变得微不足道
添加值类型语义意味着覆盖GetHashCode、Equals、add运算符==和运算符!=最好用它自己的等式(T)实现IEnumerable。如我所说,完成所有这些之后,列表操作将变得微不足道
可以在最后添加数据排序,如:
list1
.Concat(list2)
.Concat(list3)
...
.Concat(listN)
.Distinct()
.OrderBy(x => x.ItemCode)
.ThenBy(x => x.ShortName)
.ThenBy(x => x.Description);
方法1:修改模型
首先实现Equals
和GetHashCode
。然后,您可以将所有列表添加到一个列表中,选择这三个键并使用Distinct
删除重复项,然后使用OrderBy
-然后按进行排序:
public class PriceVarianceSupersetDisplayData
{
public String ShortName { get; set; }
public String ItemCode { get; set; }
public String Description { get; set; }
public override bool Equals(object obj)
{
var pv = obj as PriceVarianceSupersetDisplayData;
if (pv == null)
return false;
return this.ShortName == pv.ShortName
&& this.ItemCode == pv.ItemCode
&& this.Description == pv.Description;
}
public override int GetHashCode()
{
return 0;
}
}
Func<PriceVarianceData, PriceVarianceSupersetDisplayData> selector =
(p => new PriceVarianceSupersetDisplayData()
{
ShortName = p.ShortName,
ItemCode = p.ItemCode,
Description = p.Description
});
List<PriceVarianceSupersetDisplayData> results =
craftworksPVDList.Concat(chophousePVDList)
.Concat(gordonbierschPVDList)
.Concat(oldchicagoPVDList)
.Concat(oldchifranchisePVDList)
.Concat(rockbottomPVDList).Select(selector).Distinct()
.OrderBy(x=> x.ItemCode).ThenBy(x=> x.ShortName)
.ThenBy(x=> x.Description).ToList();
方法1:修改模型
首先实现Equals
和GetHashCode
。然后,您可以将所有列表添加到一个列表中,选择这三个键并使用Distinct
删除重复项,然后使用OrderBy
-然后按进行排序:
public class PriceVarianceSupersetDisplayData
{
public String ShortName { get; set; }
public String ItemCode { get; set; }
public String Description { get; set; }
public override bool Equals(object obj)
{
var pv = obj as PriceVarianceSupersetDisplayData;
if (pv == null)
return false;
return this.ShortName == pv.ShortName
&& this.ItemCode == pv.ItemCode
&& this.Description == pv.Description;
}
public override int GetHashCode()
{
return 0;
}
}
Func<PriceVarianceData, PriceVarianceSupersetDisplayData> selector =
(p => new PriceVarianceSupersetDisplayData()
{
ShortName = p.ShortName,
ItemCode = p.ItemCode,
Description = p.Description
});
List<PriceVarianceSupersetDisplayData> results =
craftworksPVDList.Concat(chophousePVDList)
.Concat(gordonbierschPVDList)
.Concat(oldchicagoPVDList)
.Concat(oldchifranchisePVDList)
.Concat(rockbottomPVDList).Select(selector).Distinct()
.OrderBy(x=> x.ItemCode).ThenBy(x=> x.ShortName)
.ThenBy(x=> x.Description).ToList();
如果您不想为Equals
/GetHashCode
重写或实现IEqualityComparer而烦恼,如果您不想为Equals
/GetHashCode
重写或实现IEqualityComparer而烦恼,那么可以轻松完成。但首先,craftworksPVDList
,chophouse pvdlist
,gordonbierschPVDList
,等等。。。都是同一类型的吗?或者你的意思是结果应该是类型PriceVarianceSupersetDisplayData
@user3185569:是的,所有你列出的都是PriceVarianceData的列表,但其中的“最小化版本”(“PriceVarianceSupersetDisplayData”,可能命名错误)是存储合并结果的地方。这更简单,检查我下面的方法。这很容易做到。但首先,craftworksPVDList
,chophouse pvdlist
,gordonbierschPVDList
,等等。。。都是同一类型的吗?或者您的意思是结果的类型应该是PriceVarianceSupersetDisplayData
@user3185569:是的,所有