Split List into multiple lists of similar values C# [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a parent list something like so :-
ParentList = {a,b,c,a,c,d,b,a,c,c}
I want to split this list into smaller list something like :-
ListA = {a,a,a} ListB = {b,b} ListC= {c,c,c,c} ListD = {d}
My main intention is to get the count of the highest occurring value. In the case above it would be 4 which is the count of ListC.
How can I split the parent list into small list like stated in example. Or is there a way I can get the greatest count without the list splitting.
Any help is appreciated.

Use GroupBy to group similar values and then count the amount of items in each group:
var result = ParentList.GroupBy(item => item)
.Select(group => new {
Key = group.Key,
Count = group.Count() })
.OrderByDescending(item => item.Count);
You can also use query syntax:
var result = from item in ParentList
group 1 by item into g
order by g.Count() descending
select new { Key = g.Key, Count = g.Count() };
If you really want different collections with different variables to them, as in your description above then you need to retrieve from the snippet each collection. You can also use ToDictionary on the result of the grouping.

Assuming you just want the count, and not which character/string gives that count, here is a one liner (you'll need using System.Linq;)
var highestCount = ParentList.GroupBy(p => p).Max(p => p.Count());

string maxRepeated = ParentList.GroupBy(s => s)
.OrderByDescending(s => s.Count())
.First().Key;

A simple way to do this would be using LINQ
var chars = new[] { 'a', 'b', 'c', 'a', 'c', 'd', 'b', 'a', 'c', 'c' };
var largetstGroup = chars
.GroupBy(_ => _) // Group items by the letter this will yield groups (aka lists) that will conatin only each letter
.OrderByDescending(_ => _.Count()) //Order by the items in each list
.FirstOrDefault(); // get the first one
If you have more complex objects in your list, where the GroupBy method is used you can specify any property to perform the grouping by (ex, for a list of Persons you could group by age GroupBy(_=> _.Age)

Related

Alphabetic GroupBy in Linq with a twist

I have a tricky question. I'm looking for the most concise, hackiest way of achieving the following:
query = (from book in library.books.OrderBy(x=>x.title)
group book by
new { title = book.title[0].ToString(), yadiyada="" });
The result of which is all of the books in the library grouped by the first letter. Yadiyada is because my group object is not a simple string but an object.
I'm wondering if there's a pure LINQ way of making it so that the grouping is 'A', 'B', 'C', ... 'Z', but all others fall into a single grouping called '123!##'.
In other words, I want only one grouping for all non alpha characters (A->Z + Rest).
I can do this in many ways if I get verbose (currently I'm simply making a union of two Linq statements), but that's not the purpose of this question. I'm wondering if someone can come up with a really neat way of doing it...
It depends on what a pure LINQ way means. If you want to group it with a single query, you can try something like this:
query = (from book in library.books.OrderBy(x=>x.title)
let c = book.title[0]
group book by
new { title = char.IsLetter(c) ? c.ToString() : "123!##", yadiyada="" });
I think you want some kind of conditional grouping. You could use the null character as placeholder for all non alpha characters:
HashSet<char> alpha = new HashSet<char>("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvqxyz");
var query = books
.OrderBy(b => b.title)
.Select(b => new{ Book = b, IsAlpha = alpha.Contains(b.title[0]), Char = b.title[0]} )
.Select(x => new{ x.IsAlpha, x.Book, Char = x.IsAlpha ? x.Char : '\0' } )
.GroupBy(x => x.Char);

Use LINQ to group multiple columns & split data into several lists

Recently I have a task which need to do as following description, my question is that is LINQ capable to do it?
Say I have a set of data, each consists of three columns: a(int),b(int),c(int)
What I want to do is to group these data by a and b, and for each distinct pair (a,b), store their corresponding c into separate list.
For example: If I have a set of data(a,b,c) {(1,3,5), (2,4,6), (1,3,7), (2,4,8)},
I want to split the data into two separate list, each contains c's value:
List 1 (a=1,b=3) : [5,7]
List 2 (a=2,b=4) : [6,8]
What I have tried is to group / order by the data by (a,b), and got a sorted list of data, I can of course use any loop to iterate the set of data and split them into several list, just wondering if there is a more beautiful solution, like using a single LINQ query?
Any suggetion is pleased! Thanks :)
Try this:
var result = data.GroupBy(x => new { x.a, x.b })
.Select(g => Tuple.Create
(
new List<int> { g.Key.a, g.Key.b },
new List<int>(g.Select(x => x.c))
)).ToList();
Here's the query expression equivalent:
var result = (from x in data
group x by new { x.a, x.b } into g
select Tuple.Create(
new List<int> { g.Key.a, g.Key.b },
new List<int>(g.Select(x => x.c)))).ToList();

Group by custom list linq c# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have problem in understanding custom group by and order by. Here is the scenario,
I have an object contain data.
Objects->object->name; (structure of the object)
and i want to group by custom list that i have (name is the key object for grouping).
name is like a,b,c and i want b,c,a(sample).
Here is my work around
IOrderedEnumerable<IGrouping<string, Snit>> assetGrouping = sUnits.ToArray().GroupBy(e => e.Name).OrderBy(e => e.Key);
and i want to group and order by my custom list
List<string > customOrder=new List<string>();
customOrder.Add("any");
customOrder.Add("some");
can any body help me..
This is what I scrapped using LINQPad:
Prerequisites:
public class Data
{
public string Name {get; set;}
}
var keys = new[]{"1", "15", "13", "16"};
var random = new Random();
var data = Enumerable.Range(1, 100)
.Select( _ => new Data
{
Name = random.Next(24).ToString()
});
var keys = new[]{"1", "15", "13", "16"};
Now, the grouping:
var grouped = data.GroupBy(x => keys.FirstOrDefault(k=>k==x.Name));
The query above will group the items in data as following: for each value x in data, if there is a key k in keys with k == x.Name, the value will be added to a separate group having the key k; all the other values will be added to a separate group having the key null;
For the ordering of the groups you just need to use the position of each group key in the keys array.
var ordered = grouped.OrderBy( g =>
{
var index = Array.IndexOf(keys, g.Key);
return index == -1 ? int.MaxValue : index;
});
Array.IndexOf will return -1 if the item wasn't found in the dictionary. In this case, according to your needs, the item must be at the end of the collection so return max value. Otherwise, just use the index of the key.
The results are in the image below:

C# List values compare and add

var bndlSummary = GetBundleSummary(GroupIds);
var cntrSummary = GetContainerSummary(GroupIds);
var finalSummary = GetFinalSummary(GroupIds);
Above var are fetching some data from Database. They all have one Common Field Name "City".
City value can be repeated many time like City = Chicago can be 3 times or more). now I want this Field City value into allCityNames. I don't want City Info to be repeated from any var.
var allCityNames = new cityAnalysisSummary();
Please help me how how should i do it. Thank you very much for your help.
bndlSummary.Select(b => b.City)
.Concat(cntrSummary.Select(c => c.City))
.Concat(finalSummary.Select(f => f.City))
.Distinct();
Use Select to get all the cities from each collection, Concat to put them all together, and Distinct to remove any duplicates.
You can also use Union which will remove duplicates while concatenating:
bndlSummary.Select(b => b.City)
.Union(cntrSummary.Select(c => c.City))
.Union(finalSummary.Select(f => f.City));

How to select common items

Work on C# linq.I have a list to list.From this list I want to get the common items
List<SQLFrameWorkTableEntity> oParent = new List<SQLFrameWorkTableEntity>();
List<List<SQLFrameWorkTableEntity>> oChild = new List<List<SQLFrameWorkTableEntity>>();
oListParentTable = oList.Where(p => p.Parent == true).ToList();
foreach (SQLFrameWorkEntity item in oListParentTable)
{
oChild.Add(GetTableSchemaList(item, oParent));
}
Above picture describe how my oChild is.
Now this oChild is the list of list SQLFrameWorkTableEntity.I want to get the common items from the oChild.How to get it?If have any query plz ask.Thanks in advance
After replace List to List> ,I write the bellow linq syntax
var r=oChild.Select(p => p.Select(x => p.Any(y => y.ColumnName == x.ColumnName))).ToList();
Here, in r i get all list item are true,that means i fail to compare with list to list.Help me to correction this syntax.Thanks
So you want to find the items that occur in all lists produced by GetTableSchemaList(item, oParent)? Let's assume yes.
First add Distinct() (if one list is not distinct yet):
oChild.Add(GetTableSchemaList(item, oParent).Distinct());
Then after the foreach do:
var count = oListParentTable.Count;
var r = oChild.SelectMany(i => i).GroupBy(i => i)
.Where(g => g.Count() == count).SelectMany(i => i).Distinct();
The idea is that "common items" should occur exactly, say, 4 times in the flattened list of lists (SelectMany) when the number of distinct lists in oChild is 4.

Categories

Resources