Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从多个列表中选择不同且有序的数据到通用列表中?_C#_Linq_Generic List - Fatal编程技术网

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:是的,所有