Group by custom list linq c# [closed] - c#

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:

Related

In a string list how to split by every 2 character and insert a comma [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 4 years ago.
Improve this question
I have a list string which has values like below, could you please let me know how to split the list by every 2 character and insert a comma separated and assign the final list to another list.
var list1 = new List<string>() {"DVMNKL"};
var list2 = new List<string>() {"DV","MN","KL"};
Some time list1 can have only 2 character, at that time I should not split, I have to just assign to list2
You can use System.Linq to manage that.
int splitByCount = 2;
string s = new List<string> { "DVMNLS", "DVMNLS" };
var split = s.SelectMant(c => c) //flatten the list of strings to IEnumerable<char>
.Select((c, index) => new {c, index})
.GroupBy(x => x.index/splitByCount)
.Select(group => group.Select(elem => elem.c))
.Select(chars => new string(chars.ToArray()));
Console.WriteLine(string.Join(",", split));
the output
DV,MN,KL,DV,MN,KL

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

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)

Get unique items from multiple lists using LINQ- C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have 3 lists.
ListA<items>
ListB<items>
ListC<items>
I have to select one item from each list but the item.itemID should be unique for each of those items. How can i achieve this? Thanks in advance.
List<items> concat = new List<items>();
concat.AddRange(ListA);
concat.AddRange(ListB);
concat.AddRange(ListC);
List<items> result = new List<items>();
foreach (var item in concat)
{
if (result.Where(x => x.itemId == item.itemId).Count() == 0)
{
result.add(item);
}
}
//result should now contain what you are looking for
So you want exactly one item from each list, where that item hasn't been selected already from a previous list?
Then select from the lists where the ID isn't in the previous selection. Maybe something like this:
var itemA = listA.First(); // any item is unique, since this is our first one
var itemB = listB.First(b => b.ID != itemA.ID);
var itemC = listC.First(c => c.ID != itemA.ID && c.ID != itemB.ID);
If the count of lists isn't known then we'd need to make this a little more dynamic. Maybe something like this:
var selectedItems = new List<Item>();
foreach (var list in listOfLists)
selectedItems.Add(list.First(x => selectedItems.Count(y => y.ID == x.ID) == 0));
What this does is loop through the "list of lists" (since the number of lists isn't known, it must be in a collection data structure) and get the first item from each one where the currently known selected items do not have a matching ID. This should result in one selected item from each list.
(This all assumes that the lists contain a valid item that you're looking for. If that's not the case, you might use FirstOrDefault() instead and check for nulls.)
public class items
{
public int id {get;set;}
}
void Main()
{
var l1=new List<items>{new items {id=1}, new items {id=2}, new items {id=3}};
var l2=new List<items>{new items {id=2}, new items {id=3}, new items {id=4}};
var l3=new List<items>{new items {id=1}, new items {id=2}};
var result=l1
.Join(l2,(k1)=>true,(k2)=>true,(a1,a2)=>new {a1,a2})
.Join(l3,(k1)=>true,(k2)=>true,(b1,b2)=>new {b1.a1,b1.a2,a3=b2})
.Where(rec=>rec.a1.id!=rec.a2.id && rec.a2.id!=rec.a3.id && rec.a1.id!=rec.a3.id)
.First();
Console.WriteLine("{0},{1},{2}",result.a1.id,result.a2.id,result.a3.id);
}
Of the possible answers (132,142,231,241,321,341,342) it will pick and return the first one (132).
Example code: http://csharppad.com/gist/98a076bdd4e01dbd82be

dynamic list in 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 9 years ago.
Improve this question
if(some condition)
{
var columnSeries = (from l in logs
group l by l.MonitoringPorfileName into grp
select new
{
type = "column",
name = grp.Key,
data = (from h in Hours
let gd = grp.Where(x => x.Hours == h)
select gd.Sum(x => x.Count)).ToArray()
}).ToList();
}
}
How can i make this variable columnSeries a global variable? i have searched a lot on this, found list dynamic> new{}; but none of them are working so help will be really appreciated
Make the anonymous type you want a class.
public class ColumnSeries
{
public string type {get; set;}
//...
}
//class level variable
IEnumerable<ColumnSeries> columnSeries = null;
//then create the ColumnSeries list
columnSeries = (from l in logs
group l by l.MonitoringPorfileName into grp
select new ColumnSeries
{
type = "column",
name = grp.Key,
data = (from h in Hours
let gd = grp.Where(x => x.Hours == h)
select gd.Sum(x => x.Count)).ToArray()
});
You are creating an anonymous type inside your if statment but you want to use the result ouside the scope of the if statement. Usually you just define 'columnSeries' before the if BUT this is an anonymous type so it's not obvous.
So, before the if statement do the following (untested but should be close):
var columnSeries = Enumerable.Repeat(new {type="", name="", data=new int[]{0}}, 0);
Check out this question for more info

Working with List [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 two list : (Note: List's Items are combination of "NAME" & "ID" )
List<string> ListA = new List() {"SAM001","SAM002","SAM003","PIT001","PIT002","PIT004","ROSE001","ROSE002","JASE001" };
//so on
List<string> ListB = new List() {"SAM001","SAM003","PIT000","ROSE002","JASE001","INDI000"};`
//so on...
Now Based on these two list i want to create two new list suppose listCommon & listUncommon.
listCommon will contain all matched items of ListA & ListB.
listUnCommon will contain all remaining items of ListA
Now My condition is if Any item in ListB has NAME + 000 then all the items of ListA starting with that Name should add in my listCommon.
Example 1 : if ListB item is PIT000 and ListA item are PIT001,PIT002,PIT003,ABC001
then listCommon = PIT001,PIT002,PIT003 because ListB has PIT with 000 so condition true all ListA 'PIT' items added in listcommon
So as above list and my condition i want my final list below
List<string> listCommon = new List() {"SAM001","SAM003", "PIT001","PIT002","PIT004","ROSE002", "JASE001" };
List<string> listUncommon = new List() {"SAM002", "ROSE001"};
Please suggest..i just spend my couple of minutes in loops but not getting actual result as i mentioned :(
This should work.
var common = ListA.Intersect(ListB)
.Concat(
ListA.Where(a =>
ListB.Any(
b => b.EndsWith("000") &&
b.StartsWith(a.Substring(0, a.Length - 3))
)
)
);
var uncommon = ListA.Except(common);
Using an insersect, then you are selecting any from list A where list B has an entry that matches the first 3 letters and ends with 000.
This is not the most efficient way of doing this, however it is terse code-wise.
Finding the common items from 2 lists:
var listCommon = list1.Intersect(list2);
Updated - Subtracted items:
var subtractedItems = new HashSet(listCommon);
commonItems.ExceptWith(list1);

Categories

Resources