Home > Blockchain >  Linq group by condition
Linq group by condition

Time:10-27

I provide the simple list as below :

var records = new List<BookRecord> {
            new() {
                Author = "Peter",
                BookName = "Book A"
            },
            new() {
                Author = "",
                BookName = "Book B"
            },
            new() {
                Author = "Peter",
                BookName = "Book C"
            },
            new() {
                Author = "James",
                BookName = ""
            },
            new() {
                Author = "",
                BookName = "Book D"
            },
            new() {
                Author = "James",
                BookName = ""
            },
            new() {
                Author = "",
                BookName = "Peter"
            }
        };

I want to group only author is not empty (or other condition) , and the remain need to keep into result , so my expected result will be :

[
  {"Author":"Peter","BookName":"Book A"},
  {"Author":"","BookName":"Book B"},
  {"Author":"James","BookName":""},
  {"Author":"","BookName":"Book D"},
  {"Author":"","BookName":"Peter"}
]

and need to in ordering (that mean "james" should be row 3 and the last one must be {"Author":"","BookName":"Peter"}

can I know how to do it ?

Thank you

CodePudding user response:

Hey You can use this :)

var filteredRecords = records
            .Where(x => x.Author != "") //condition
            .OrderBy(x=> x.Author)  // Order by 
            .ToList();

Result will be

Author :James - BookName: 
Author :James - BookName: 
Author :Peter - BookName: Book A
Author :Peter - BookName: Book C

Example code here https://dotnetfiddle.net/cxYVTY

CodePudding user response:

As far as I can see you want

  1. If Author is set (not an empty string) return his/her first book only.
  2. If Author is not set just return the record.

If it's your case, you can either GroupBy followed by Select First:

int index = 0;

var result = source
  .GroupBy(item => (item.Author, string.IsNullOrEmpty(item.Author) ?   index : 0))
  .Select(group => group.First());

The trick is to make all groups with empty Author being unique which we do with a help of index.

If we don't want to use side effects with index we can exploit the same idea but with longer query:

var result = source
  .Select((value, index) => (value, index))
  .GroupBy(pair => (pair.value.Author, string.IsNullOrEmpty(pair.value.Author) 
                      ?   pair.value.index 
                      : 0),
           pair => pair.value)
  .Select(group => group.First());
  • Related