Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# LINQ-按多个列分组并合并结果_C#_Linq - Fatal编程技术网

C# LINQ-按多个列分组并合并结果

C# LINQ-按多个列分组并合并结果,c#,linq,C#,Linq,我正在处理相当大的一组数据(~130000条记录),我已经设法以我想要的方式将其转换为csv 下面是列表的简化示例: 现在,如果第1列、第2列和第3列匹配,我想合并这些记录,如下所示: 输出 "Surname1, Name1;Address1;State1;YES;Group1" "Surname2, Name2;Address2;State2;YES;Group2 Group1" "Surname3, Name3;Address3;State3

我正在处理相当大的一组数据(~130000条记录),我已经设法以我想要的方式将其转换为csv

下面是列表的简化示例:

现在,如果第1列、第2列和第3列匹配,我想合并这些记录,如下所示:

输出

"Surname1, Name1;Address1;State1;YES;Group1"
"Surname2, Name2;Address2;State2;YES;Group2 Group1"
"Surname3, Name3;Address3;State3;NO;Group1"
"Surname1, Name1;Address2;State1;YES;Group1"
以下是到目前为止我得到的信息:

output.GroupBy(x => new { c1 = x.Split(';')[0], c2 = x.Split(';')[1], c3 = x.Split(';')[2] }).Select(//have no idea what should go here);

首先尝试获取以匿名类型投影结果所需的列:

var query=  from r in output
            let columns= r.Split(';')
            select new { c1 =columns[0], c2 =columns[1], c3 = columns[2] ,c5=columns[4]};
然后创建组,但现在使用在上一个查询中定义的匿名对象:

var result= query.GroupBy(e=>new {e.c1, e.c2, e.c3})
                 .Select(g=> new {SurName=g.Key.c1,
                                  Name=g.Key.c2,
                                  Address=g.Key.c3,
                                  Groups=String.Join(",",g.Select(e=>e.c4)});
我知道我遗漏了一些专栏,但我想你可以理解


PS:我在两个查询中分离逻辑的事实只是为了可读性,您可以在一个查询中组合两个查询,但这不会改变性能,因为LINQ使用

首先尝试获取以匿名类型投影结果所需的列:

var query=  from r in output
            let columns= r.Split(';')
            select new { c1 =columns[0], c2 =columns[1], c3 = columns[2] ,c5=columns[4]};
然后创建组,但现在使用在上一个查询中定义的匿名对象:

var result= query.GroupBy(e=>new {e.c1, e.c2, e.c3})
                 .Select(g=> new {SurName=g.Key.c1,
                                  Name=g.Key.c2,
                                  Address=g.Key.c3,
                                  Groups=String.Join(",",g.Select(e=>e.c4)});
我知道我遗漏了一些专栏,但我想你可以理解


PS:我在两个查询中分离逻辑的事实只是为了可读性,您可以在一个查询中组合两个查询,但这不会改变性能,因为LINQ使用

我会这样做:

class Program
{
    static void Main(string[] args)
    {
        List<string> input = new List<string> {
            "Surname1, Name1;Address1;State1;YES;Group1",
            "Surname2, Name2;Address2;State2;YES;Group2",
            "Surname2, Name2;Address2;State2;YES;Group1",
            "Surname3, Name3;Address3;State3;NO;Group1",
            "Surname1, Name1;Address2;State1;YES;Group1",
    };
        var transformed = input.Select(s => s.Split(';'))
            .GroupBy(   s => new string[] { s[0], s[1], s[2], s[3] }, 
                        (key, elements) => string.Join(";", key) + ";" + string.Join(" ", elements.Select(e => e.Last())), 
            new MyEqualityComparer())
            .ToList();

    }
}

internal class MyEqualityComparer : IEqualityComparer<string[]>
{
    public bool Equals(string[] x, string[] y)
    {
        return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
    }

    public int GetHashCode(string[] obj)
    {
        int hashCode = obj[0].GetHashCode();
        hashCode = hashCode ^ obj[1].GetHashCode();
        hashCode = hashCode ^ obj[2].GetHashCode();
        return hashCode;
    }
}
类程序
{
静态void Main(字符串[]参数)
{
列表输入=新列表{
“姓1,名1;地址1;状态1;是;组1”,
“姓2,名2;地址2;状态2;是;组2”,
“姓2,名2;地址2;状态2;是;组1”,
“姓氏3,姓名3;地址3;状态3;编号;组1”,
“姓1,名1;地址2;状态1;是;组1”,
};
var transformed=input.Select(s=>s.Split(';'))
.GroupBy(s=>新字符串[]{s[0],s[1],s[2],s[3]},
(key,elements)=>string.Join(“;”,key)+“;”+string.Join(“,elements.Select(e=>e.Last()),
新建MyEqualityComparer())
.ToList();
}
}
内部类MyEqualityComparer:IEqualityComparer
{
公共布尔等于(字符串[]x,字符串[]y)
{
返回x[0]==y[0]&&x[1]==y[1]&&x[2]==y[2];
}
public int GetHashCode(字符串[]obj)
{
int hashCode=obj[0].GetHashCode();
hashCode=hashCode^obj[1]。GetHashCode();
hashCode=hashCode^obj[2]。GetHashCode();
返回哈希码;
}
}
将前4列视为分组键,但仅使用前3列进行比较(因此使用自定义
IEqualityComparer
)。
然后,如果您有(键,元素)组,则对其进行变换,以便将键的元素与;(请记住,键由前4列组成)并将组中每个成员的最后一个元素添加到其中,并用空格连接。

我将这样做:

class Program
{
    static void Main(string[] args)
    {
        List<string> input = new List<string> {
            "Surname1, Name1;Address1;State1;YES;Group1",
            "Surname2, Name2;Address2;State2;YES;Group2",
            "Surname2, Name2;Address2;State2;YES;Group1",
            "Surname3, Name3;Address3;State3;NO;Group1",
            "Surname1, Name1;Address2;State1;YES;Group1",
    };
        var transformed = input.Select(s => s.Split(';'))
            .GroupBy(   s => new string[] { s[0], s[1], s[2], s[3] }, 
                        (key, elements) => string.Join(";", key) + ";" + string.Join(" ", elements.Select(e => e.Last())), 
            new MyEqualityComparer())
            .ToList();

    }
}

internal class MyEqualityComparer : IEqualityComparer<string[]>
{
    public bool Equals(string[] x, string[] y)
    {
        return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
    }

    public int GetHashCode(string[] obj)
    {
        int hashCode = obj[0].GetHashCode();
        hashCode = hashCode ^ obj[1].GetHashCode();
        hashCode = hashCode ^ obj[2].GetHashCode();
        return hashCode;
    }
}
类程序
{
静态void Main(字符串[]参数)
{
列表输入=新列表{
“姓1,名1;地址1;状态1;是;组1”,
“姓2,名2;地址2;状态2;是;组2”,
“姓2,名2;地址2;状态2;是;组1”,
“姓氏3,姓名3;地址3;状态3;编号;组1”,
“姓1,名1;地址2;状态1;是;组1”,
};
var transformed=input.Select(s=>s.Split(';'))
.GroupBy(s=>新字符串[]{s[0],s[1],s[2],s[3]},
(key,elements)=>string.Join(“;”,key)+“;”+string.Join(“,elements.Select(e=>e.Last()),
新建MyEqualityComparer())
.ToList();
}
}
内部类MyEqualityComparer:IEqualityComparer
{
公共布尔等于(字符串[]x,字符串[]y)
{
返回x[0]==y[0]&&x[1]==y[1]&&x[2]==y[2];
}
public int GetHashCode(字符串[]obj)
{
int hashCode=obj[0].GetHashCode();
hashCode=hashCode^obj[1]。GetHashCode();
hashCode=hashCode^obj[2]。GetHashCode();
返回哈希码;
}
}
将前4列视为分组键,但仅使用前3列进行比较(因此使用自定义
IEqualityComparer
)。 然后,如果您有(键,元素)组,则对其进行变换,以便将键的元素与;(请记住,键由前4列组成)并将组中每个成员的最后一个元素添加到键中,并用空格连接