Convert List<int> to a Dictionary<int,int> using LINQ - c#

Say I have the following list:
List<int> list = new List<int>() { 5, 5, 6, 6, 6, 7, 7, 7, 7 };
How could I convert the list to a Dictionary where the value is the count of each distinct number in the list by using LINQ? For example, the above list should be converted to a dictionary with the elements:
key -> value
5 -> 2
6 -> 3
7 -> 4

var result = list.GroupBy(i => i).ToDictionary(g => g.Key, g => g.Count());

Efficent solution (only 1 iteration over collection):
var output = new Dictionary<int, int>();
foreach (var val in list)
{
if (!output.ContainsKey(val))
{
output.Add(val, 1);
}
else
{
output[val] = output[val] + 1;
}
}

var group = list.GroupBy(T => T).ToDictionary(T => T.Key, T => T.Count())

try this:
var dic = list.GroupBy(c => c)
.Select(c => new {c.Key, Count = c.Count()})
.ToDictonary(c => c.Key, q => q.Count)

Related

LINQ - Join both lists by last digit

A sequence of positive integers integerList1 and integerList2 are given. All values in each sequence are different.
Get a set (list of NumberPair values) of all value pairs that satisfy the following conditions:
the first element of the pair belongs to the sequence integerList1,
the second belongs to
integerList2
both elements end with the same digit.
The NumberPair type includes
Value 1, Value 2 fields.
The resulting NumberPair list must be sorted in ascending order
by the first field, and if they are equal, by the second.
Here is an example:
integerList1: new[] { 1, 12, 4, 5, 78 }
integerList2: new[] { 1, 42, 75, 65, 8, 97 }
Expected result:
expected: new[]
{
new NumberPair{Item1 = 1, Item2 = 1},
new NumberPair{Item1 = 5, Item2 = 65},
new NumberPair{Item1 = 5, Item2 = 75},
new NumberPair{Item1 = 12, Item2 = 42},
new NumberPair{Item1 = 78, Item2 = 8}
}
I tried to solve like this
var lastDigitsGroups1 = integerList1.GroupBy(num => num % 10).ToDictionary(kvp => kvp.Key, kvp => kvp.ToList());
var lastDigitsGroups2 = integerList2.GroupBy(num => num % 10).ToDictionary(kvp => kvp.Key, kvp => kvp.ToList());
var intersection = lastDigitsGroups1.Keys.Intersect(lastDigitsGroups2.Keys);
foreach (var item in intersection)
{
var np = new NumberPair { Item1 = lastDigitsGroups1[item].FirstOrDefault(), Item2 = lastDigitsGroups2[item].FirstOrDefault() };
yield return np;
}
However, it should be done only using LINQ and even with one LINQ query.
Join both lists by keys as below:
var result = (from a in integerList1
join b in integerList2 on (a % 10) equals (b % 10)
select new NumberPair { Item1 = a, Item2 = b }
)
.OrderBy(x => x.Item1)
.ThenBy(x => x.Item2)
.ToList();
Or
var result = integerList1.Join(integerList2,
x => x % 10,
y => y % 10,
(x, y) => new { x, y })
.Select(x => new NumberPair { Item1 = x.x, Item2 = x.y })
.OrderBy(x => x.Item1)
.ThenBy(x => x.Item2)
.ToList();
Demo # .NET Fiddle
I honestly don't understand your approach, it does not seem to do what you have mentioned in your conditions. If i just take them as requirement, use Enumerable.Zip:
var result = integerList1.Zip(integerList2, (i1, i2) => new NumberPair{Item1 = i1, Item2 = i2} )
.OrderBy(np => np.Item1)
.ThenBy(np => np.Item2);

How get max count with min key from list integer with linq written in one expression

For example I have following list
var arr = new List<int> { 1, 4, 4, 4, 5, 3 };
I implemented as:
var res1 = from type in arr
group type by type into ByrdTypes
select new
{
Group = ByrdTypes.Key,
Count = ByrdTypes.Count()
};
var correct = from item in res1
where item.Count == res1.Max(y => y.Count)
select item;
var result = correct.Min(x => x.Group);
This is working solution. But how can I rewrite this in one Linq expression(query)? Thank you.
You could just use OrderBy or OrderByDescending then First or Last
var list = new List<int>() { 1, 4, 4, 4, 5, 3 };
var result = list
.GroupBy(type => type)
.Select(x => new {Group = x.Key, Count = x.Count()})
.OrderByDescending(x => x.Count)
.First();
// The above will get you the group with the highest count
Console.WriteLine(result);
Output
{ Group = 4, Count = 3 }

List of most occurrences of element

I have a list let's say {1,1,2,2,3,3,3,4,4,4}. I want to find a List of the elements that occur the most often (it has to be a list as there can be a situation like here that 3 and 4 occur most and I need to get that information. How can I achieve this using LINQ?
var highCountItems = source
.GroupBy(item => item)
.GroupBy(g => g.Count(), g => g.Key)
.OrderByDescending(counts => counts.Key)
.First();
int theCount = highCountItems.Key;
var theItems = highCountItems.ToList();
By Grouping:
var grp = list.GroupBy(i => i).ToList();
int max = grp.Max(c => c.Count());
var most = grp.Where(d => d.Count() == max)
.Select(c => c.Key).ToList();
First you will have to group the numbers followed by ordering them so you will get the most frequently occurring number on the top.
int[] numbers = { 1, 1, 2, 2, 3, 3, 3, 4, 4, 4 };
var groups = numbers.GroupBy(i => i).OrderByDescending(g => g.Count());
foreach (var group in groups)
{
// group.Key -> Represents the number in the list
}
The groups variable will contain all the groups formed from the numbers list ordered by their occurrence, meaning the first group will be the top most occurring group followed by the next. In case of same occurrences, the groups will be ordered by their occurrence in the list for example 3 & 4 have equal occurrences whereas 3 comes first before 4 and hence the group formation will be in same order.
A little complicated
var lst_input = new List<int>(new int[] { 1, 1, 2, 2, 3, 3, 3, 4, 4, 4 });
var result = lst_input.Where(x => lst_input.Max(y => lst_input.Count(z => z == y)) == lst_input.Count(z => z == x)).Distinct().ToList();
But the above code is not effective when dealing with a really big array, since finding max is re-run for each element, and we could distinct the list in the first place. Another more efficient way:
var lst_input = new List<int>(new int[] { 1, 1, 2, 2, 3, 3, 3, 4, 4, 4 });
var tmp = lst_input.Distinct();
var max_val = tmp.Max(y => lst_input.Count(z => z == y));
var result = tmp.Where(x => max_val == lst_input.Count(z => z == x)).ToList();

How to simultaneously sort 2 lists using LINQ?

I have two lists { 7 3 5 } and {9 8 1}.
I want to sort my first list and I want the second list to have the same index permutation as given by the first list.
{3 5 7} => {8 1 9}
Is it possible to do this in a single LINQ statement?
Sounds like you might want:
var list1 = new List<int> { 7, 3, 5 };
var list2 = new List<int> { 9, 8, 1 };
var orderedZip = list1.Zip(list2, (x, y) => new { x, y } )
.OrderBy(pair => pair.x)
.ToList();
list1 = orderedZip.Select(pair => pair.x).ToList();
list2 = orderedZip.Select(pair => pair.y).ToList();
You could try using the Zip method:
var sortedPairs = list1
.Zip(list2, (item1, item2) => new KeyValuePair<int, int>(item1, item2))
.OrderBy(pair => pair.Key);
Then you could get the first sorted list by:
var sortedList1 = sortedPairs.Select(pair => pair.Key);
And the second list by:
var sortedList2 = sortedPairs.Select(pair => pair.Value);

how would i use linq to find the most occured data in a data set?

List<int> a = 11,2,3,11,3,22,9,2
//output
11
This may not be the most efficient way, but it will get the job done.
public static int MostFrequent(IEnumerable<int> enumerable)
{
var query = from it in enumerable
group it by it into g
select new {Key = g.Key, Count = g.Count()} ;
return query.OrderByDescending(x => x.Count).First().Key;
}
And the fun single line version ...
public static int MostFrequent(IEnumerable<int> enumerable)
{
return (from it in enumerable
group it by it into g
select new {Key = g.Key, Count = g.Count()}).OrderByDescending(x => x.Count).First().Key;
}
a.GroupBy(item => item).
Select(group => new { Key = group.Key, Count = group.Count() }).
OrderByDescending(pair => pair.Count).
First().
Key;
Another example :
IEnumerable<int> numbers = new[] { 11, 2, 3, 11, 3, 22, 9, 2 };
int most = numbers
.Select(x => new { Number = x, Count = numbers.Count(y => y == x) })
.OrderByDescending(z => z.Count)
.First().Number;

Categories

Resources