如何使用LINQ将数组分区为多个数组?

时间:2016-06-27 08:45:21

标签: c# arrays linq

为了解释这个问题,我创建了一个简化的例子。在现实生活中,数据类有点复杂。请考虑以下数据类:

public class Data
{
    public Data(string source, string path, string information)
    {
        this.Source = source;
        this.Path = path;
        this.Information = information;
    }           
    public string Source { get; set; }
    public string Path { get; set; }        
    public string Information { get; set; }
}

现在考虑以下数组:

var array = new Data[] {
    new Data("MS", @"c:\temp\img1.jpg", "{a}"),
    new Data("IBM", @"c:\temp\img3.jpg", "{b}"),
    new Data("Google", @"c:\temp\img1.jpg", "{c}"),
    new Data("MS", @"c:\temp\img2.jpg", "{d}"),
    new Data("MS", @"c:\temp\img3.jpg", "{e}"),
    new Data("Google", @"c:\temp\img1.jpg", "{f}"),
    new Data("IBM", @"c:\temp\img2.jpg", "{g}")
};

我想通过在Path上对其进行分区并对Source上的每个分区进行排序来处理数据。输出必须如下:

c:\temp\img1.jpg
"Google":   "{c}"
"IBM":      "{f}"
"MS":       "{a}"

c:\temp\img2.jpg
"IBM":      "{g}"
"MS":       "{d}"

c:\temp\img3.jpg
"IBM":      "{b}"
"MS":       "{e}

如何使用LINQ创建这些分区?

您可以在此处使用代码:https://dotnetfiddle.net/EbKluE

5 个答案:

答案 0 :(得分:7)

您可以使用LINQ的OrderByGroupBySource对商品进行排序,并按Path对您订购的商品进行分组:

var partitioned = array
    .OrderBy(data => data.Source)
    .GroupBy(data => data.Path);

请参阅this fiddle了解演示。

答案 1 :(得分:1)

您可以像这样使用GroupByOrderBy

Dictionary<string, Data[]> result = 
    array.GroupBy(d => d.Path)
         .ToDictionary(g => g.Key, g => g.OrderBy(d => d.Source).ToArray());

这会为您提供一个以Path为键的字典。每个值都是Data的数组,其PathSource并按其function between($n, $a, $b) { return ($n-$a)*($n-$b) <= 0; } 排序。

答案 2 :(得分:1)

我会推荐lync的Group-by功能。 对于你的情况:

var queryImageNames =
    from image in array // <-- Array is your name for the datasource
    group image by image.Path into newGroup
    orderby newGroup.Key
    select newGroup;

foreach (var ImageGroup in queryImageNames)
{
    Console.WriteLine("Key: {0}", nameGroup.Key);
    foreach (var image in ImageGroup )
    {
        Console.WriteLine("\t{0}, {1}", image.Source, image.Information);
    }
}

答案 3 :(得分:1)

您可以使用Enumerable.GroupByPath属性进行分组:

var pathPartitions = array.GroupBy(x => x.Path);

foreach(var grp in pathPartitions)
{
    Console.WriteLine(grp.Key);
    var orderedPartition = grp.OrderBy(x => x.Source);
    foreach(var x in orderedPartition )
        Console.WriteLine($"\"{x.Source}\":   \"{x.Information}\"");
}

如果您想创建一个集合,可以创建一个Tuple<string, Data[]>[]

Tuple<string, Data[]>[] pathPartitions = array
    .GroupBy(x => x.Path)
    .Select(g => Tuple.Create(g.Key, g.OrderBy(x => x.Source).ToArray()))
    .ToArray();

Dictionary<string, Data[]>

Dictionary<string, Data[]> pathPartitions = array
    .GroupBy(x => x.Path)
    .ToDictionary(g => g.Key, g => g.OrderBy(x => x.Source).ToArray());

答案 4 :(得分:1)

您可以使用GroupBy并执行此操作。

    var results = array
        .GroupBy(x=>x.Path)
        .Select(x=>
            new
            { 
                Path =x.Key, 
                values=x.Select(s=> string.Format("{0,-8}:{1}", s.Source, s.Information))
                    .OrderBy(o=>o)
            })
        .ToList();

<强>输出:

c:\temp\img1.jpg
    Google  :{c}
    Google  :{f}
    MS      :{a}
c:\temp\img3.jpg
    IBM     :{b}
    MS      :{e}
c:\temp\img2.jpg
    IBM     :{g}
    MS      :{d}

选中此fiddle