I am new to C#. I have an array of lists that looks something like this:
var baskets = [
[apples, oranges, peaches],
[oranges, grapes, bananas],
[oranges, grapes, apples]
[bananas, strawberries, peaches]
]
I need to turn it into a single array with a count of each fruit like this:
var fruitCount = [
{fruit: apples , count:2},
{fruit: oranges, count: 3},
{fruit: peaches, count: 2},
{fruit: grapes, count: 2},
{fruit: bananas, count: 2},
{fruit: strawberries, count: 1}]
I was looking at LINQ's ".SelectMany" but it just seems to flatten out the array into one list. I honestly don't know how to begin. Can anyone point me to a code sample that could help?
Try this:
var result = baskests.SelectMany(x => x)
.GroupBy(x => x)
.Select(x => new {
Fruit = x.Key,
Count = x.Count()
});
This does exactly what Rahul suggested in the comment. It first flattens all fruits into one single list containing duplicates and than groups the list. Finally the Select-statement will create an anonymous instance for every group having a Fruit- and a Count-property.
You need to flatten the array with SelectMany and then group the entries:
var flattened = baskets.SelectMany(basket => basket);
var fruitCount = flattened.GroupBy(fruit => fruit,
(fruit, g) => new { fruit, count = g.Count()});
Related
I have a List<String> Fruits that stores a list of fruits the user enters.
For example Fruits = {"Apple", "Banana", "Apple", "Orange"}
I would like to count the number of occurrences of each fruit.
How do I go about this?
I come from a python background, and to solve this I would use dictionary. Any hints would be greatly appreciated
You may GroupBy the friuit name and take count of each group:
Fruits.GroupBy(x => x).Select(x => new {Name = x.Key, Count = x.Count()});
Live Demo
Utilise GroupBy followed with ToDictionary:
Dictionary<string, int> result = fruits.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
I have a problem similar to the following post:
How to merge two didctionaries in C# with duplicates
However, in the post, the solution concatenates duplicate strings. I want to do something similar, but with integers, and I don't want to concatenate them, I want to add them.
So I want this:
var firstDic = new Dictionary<string, int>
{
{"apple", 1},
{"orange", 2}
};
var secondDic = new Dictionary<string, int>
{
{"apple", 3},
{"banana", 4}
};
To be unioned in some way to become:
var thirdDic = new Dictionary<string, int>
{
{"apple", 4}, //values from the two "apple" keys added together.
{"orange", 2},
{"banana", 4}
};
Is there any quick and easy way to do this without having to do some cumbersome nested loop mess?
Just use Sum:
var thirdDic = firstDic.Concat(secondDic)
.GroupBy(o => o.Key)
.ToDictionary(o => o.Key, o => o.Sum(v => v.Value));
I've a list that contains 4 sized arrays:
These arrays have 4 elements. I want to use another list that contains these arrays' first element's count. In addition, if their first elements are same, they should be summation. For example:
list[0] = {1,2,3,4}
list[1] = {1,1,5,3}
list[2] = {1,2,5,8}
list[3] = {2,2,3,3}
list[4] = {3,5,5,6}
list[5] = {4,4,4,4}
list[6] = {4,5,5,6}
So, anotherList should be:
anotherList = {3, 1, 1, 2}
How can I do this?
EDIT: Expected result is:
anotherList = list.Select(a => a[0]) // project each array to its first item
.GroupBy(x => x) // group first items by their value
.Select(g => g.Count()) // select count of same items
.ToList();
Output:
[ 3, 1, 1, 2 ]
NOTE: GroupBy internally uses Lookup which returns groups in same order as the are added, so it seems to be what you want.
UPDATE: Approach which does not depend on internal implementation of GroupBy
anotherList = list.Select((a,i) => new { Item = a[0], Index = i })
.GroupBy(x => x.Item)
.OrderBy(g => g.Min(x => x.Index))
.Select(g => g.Count())
.ToList();
I have array of lists (string typed):
List<string>[] nodesAtLevel = new List<string>[20];
e.g:
[0] - List: "Hi", "There"
[1] - List: "Hi", "There", "Someone"
[2] - List: "Hi"
I need to write a LINQ operation that would return the array index of the biggest list.
Regard the example above, the LINQ operation should return 1 (because it has 3 items).
I know I should use "Where" and "Max" functions but I can't figure out how.
Use this query. First, you want to create a collection of objects that holds information about index of a list in the array and count of its items. Then, order this new collection by Count, select the first or last (depending on how you ordered the collection) and take an index.
var result = nodesAtLevel.Select((l, i) => new { Count = l.Count, Index = i })
.OrderByDescending(x => x.Count)
.First()
.Select(x => x.Index);
my version:
var max = nodesAtLevel.Select((l, i) => new { index = i, list = l })
.OrderBy(x => x.list.Count)
.Last().index;
Suppose we have a
var dictionary= new Dictionary<int, IList<int>>();
What I want is to ouput a sorted version of it, ordered first by keys and then by values inside a list.
E.g.
1 2, 1, 6
5 2, 1
2 1, 3
Becomes
1 1, 2, 6
2 1, 3
5 1, 2
I tried doing it inside foreach, but obviously this is a bad idea to change the thing you are iterating.
Try this:
// Creating test data
var dictionary = new Dictionary<int, IList<int>>
{
{ 1, new List<int> { 2, 1, 6 } },
{ 5, new List<int> { 2, 1 } },
{ 2, new List<int> { 2, 3 } }
};
// Ordering as requested
dictionary = dictionary
.OrderBy(d => d.Key)
.ToDictionary(
d => d.Key,
d => (IList<int>)d.Value.OrderBy(v => v).ToList()
);
// Displaying the results
foreach(var kv in dictionary)
{
Console.Write("\n{0}", kv.Key);
foreach (var li in kv.Value)
{
Console.Write("\t{0}", li);
}
}
A Dictionary is unsorted. To sort a dictionary you can use the OrderedDictionary.
To sort the lists, you can use List<T>.OrderBy()
You can use LINQ to order the contents of the dictionary like this:
var dictionary = new Dictionary<int, IList<int>>();
var orderedItems = dictionary
.OrderBy(pair => pair.Key)
.Select(new {
Key = pair.Key,
Value = pair.Value.OrderBy(i => i)});
Of course, this is rather ugly. A better option at this point is to use LINQ syntax
var orderedItems =from pair in dictionary
orderby pair.Key
let values = pair.Value.OrderBy(i => i)
select new { Key = pair.Key, Value = values };
If you need to use the resulting IEnumerable as a list or array, you can create one using ToList or ToArray. In most cases though, you can just use the IEnumerable as it is
You can loop through the dictionary items and sort each list seperately. it will look like this:
SortDictionary(dictionary);
after that:
foreach (System.Collections.Generic.KeyValuePair<int,IList<int>> list in dictionary)
{
SortDictionary( list.Value)
}