2

In order to explain the problem I've created a simplified example. In real life the data class is somewhat more complicated. Consider the following data class:

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; }
}

Now consider the following array:

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}")
};

I would like to process the data by partitioning it on the Path and sorting each partition on Source. The output needs to be like:

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}

How can I create these partitions with LINQ?

Here you can play with the code: https://dotnetfiddle.net/EbKluE

3
  • 1
    What should the output types be? A list of Tuples? Commented Jun 27, 2016 at 8:50
  • @Marcus no idea [(string,Data[])] I would guess... Commented Jun 27, 2016 at 8:56
  • 1
    @KeesC.Bakker: your sample and your exptected result are unclear. The sample contains two google+c:\temp\img1.jpg but you expect IBM. Commented Jun 27, 2016 at 8:58

5 Answers 5

7

You can use LINQ's OrderBy and GroupBy to sort your items by Source and group your ordered items by Path:

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

See this fiddle for a demo.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use GroupBy and OrderBy like this:

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

This gives you a dictionary with Path as keys. Each value is an array of Data that have this Path and are sorted by their Source.

Comments

1

I would recommend the Group-by function of lync. For your case:

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);
    }
}

Comments

1

You could use GroupBy and do this.

    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();

Output:

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}

Check this fiddle

Comments

1

You can use Enumerable.GroupBy to group by the Path property:

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}\"");
}

If you want to create a collection you could create a 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();

or a Dictionary<string, Data[]>:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.