score:3
With LINQ you can do like this:
var groupedByAuthor = list
.SelectMany(publication =>
publication.Authors.Select(author => new { author, publication }))
.GroupBy(arg => arg.author, keyValue => keyValue.publication)
.ToArray();
But this will be a little bit slower.
score:0
You can use Linq and some anonymous classes:
public class Publication
{
public List<string> Authors { get; set; }
public string Title { get; set; }
}
class Program
{
static void Main()
{
IEnumerable<Publication> publications; // YOUR DATA HERE!
var groupsByAuthor = publications.SelectMany(publication => publication.Authors.Select(author => new { Publication = publication, Author = author })).GroupBy(x => x.Author);
foreach (var gba in groupsByAuthor)
{
Console.WriteLine(gba.Key);
foreach (var pub in gba)
{
Console.WriteLine(pub.Publication.Title);
}
}
Console.ReadLine();
}
}
score:-1
You can also do it like this :
var dict = pubs.SelectMany(p => p.Authors)
.ToDictionary(
a => a,
a => pubs.Where(p => p.Contains(a)).ToList())
);
Not tested but you get the idea.
score:0
If you more concerned about clean and expressive code you may want to try creating an extension method instead brute forcing an ugly linq query. Code should look something like the following.
class Program
{
static void Main(string[] args)
{
List<Publication> test = new List<Publication>();
Dictionary<string, List<Publication>> publicationsByAuther = test.GroupByAuthor();
}
}
public static class Extensions
{
public static Dictionary<string, List<Publication>> GroupByAuther(this List<Publication> publications)
{
Dictionary<string, List<Publication>> dict = new Dictionary<string, List<Publication>>();
foreach (var publication in publications)
{
foreach (var author in publication.Authors)
{
if (dict.ContainsKey(author))
{
dict[author].Add(publication);
}
else
{
dict.Add(author, new List<Publication>
{
publication
});
}
}
}
return dict;
}
}
score:0
You might think about separating the case of adding a new author from adding a publication. Turning the code into something like that:
var dict = new Dictionary<string, List<Publication>>();
foreach (var publication in list)
{
foreach (var author in publication.Authors)
{
if (!dict.ContainsKey(author))
dict.Add(author, new List<Publication>());
dict[author].Add(publication);
}
}
It is not LINQ and not a new solution, but maybe it can help about the elegancy
Source: stackoverflow.com
Related Articles
- Using Linq to group objects that contain a list field
- Using Linq to group a list of objects that contains primitives data into a new grouped list of objects
- C# Linq or Lambda expression Group by Week IEnumerable list with date field
- Select a field that is not in Group By clause in LINQ
- Using LINQ to group a list of strings based on known substrings that they will contain
- How to group a list so that a single record for a day on a DateTime field is retrived using Linq?
- LINQ: group by a field that is a list
- LINQ Group By along with percent of list that contains element
- c# Linq or code to extract groups from a single list of source data
- linq query returning any where a class field that exists in a list
- How to write SQL translateable linq code that groups by one property and returns distinct list
- How do i group a list of dynamic objects using linq given that the property names are dynamic?
- Group objects in List by property in object that is List using LINQ
- Using Linq to group a list of objects into a new grouped list of list of objects
- LINQ query to return distinct field values from list of objects
- LINQ - Find all items in one list that aren't in another list
- How are people unit testing code that uses Linq to SQL
- LINQ select one field from list of DTO objects to array
- LINQ return items in a List that matches any Names (string) in another list
- Linq selecting items that exist in both list
- Using LINQ to group a list of objects
- Remove items from list that intersect on property using Linq
- LINQ Lambda - Find all ID's in one list that don't exist in another list
- Field concatenation based on group in LINQ
- Linq - How to select items from a list that contains only items of another list?
- Linq select records that match a list of IDs
- Is there a good source that gives an overview of linq optimizations?
- LINQ Lambda, Group by with list
- Group by key and send values into list using LINQ
- Group items in a list based on two properties using LINQ
- Merging lists in another list using LINQ c#
- LINQ Union - string keep orderby
- Order result using LINQ and cast type
- Custom aggregation functions in SQL Server vs Aggregate in Linq
- How to add hour from another column to date in Linq to SQL
- How to group XML data using LINQ in C#.net?
- SQLite Join command issue Unity
- Can't use sum in anonymous type
- string comparison with double?
- How to I use TryParse in a linq query of xml data?
- SQL Query to retrieve Count
- how to check next item in linq 2 sql query
- Why are stored procedures, functions, and views put into a .dbml file instead of the code file?
- Cast Error in Linq Query
- Why does using Linq's .Select() return IEnumerable<dynamic> even though the type is clearly defined?
- xml to linq, how to fix late binding?
- Calling a UDF in LINQ without "dbo" database user
- Understanding the => in LINQ
- advanced grouping and aggregation with linq
- XML.Linq - get value based on another value