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());
Related
I have a list with date and Fileno as values. I need to find the duplicate date and based on that find the highest Fileno.Then add that keyvalue pair and the distinct pair to the final list. The result should be as shown below.I am able to get the duplicate date but how to compare the duplicate dates and find the highest fileno?
Key Date Fileno
1 10/8/1980 1234
2 10/8/1980 1345
3 8/6/1970 4567
Result
2 10/8/1980 1345
3 8/6/1970 4567
Code
var list = new List<valuepair>();
list.Add(new valuepair {no=key,comdate=date,filnum=fileno})
Var dup= list.GroupBy(x => comdate.Value).Where(x => comdate.Count() > 1)
You're almost there, except the code you've posted is not compilable (!). You just need to take the element with the highest "filnum" from each group:
var list = new List<valuepair>();
list.Add(new valuepair { no=1, comdate="10/8/1980", filnum=1234 });
list.Add(new valuepair { no=2, comdate="10/8/1980", filnum=1345 });
list.Add(new valuepair { no=3, comdate="8/6/1970", filnum=4567 });
var listWithoutDuplicates = list.GroupBy(x => x.comdate)
// For each group (in which items have identical dates) take only
// the one with the highest "filnum"
.Select(group => group.OrderBy(x => x.filnum).First())
.ToList();
Try this:
var result = data
.GroupBy(
i => i.Date,
(key, group) => group.Single(x => x.Fileno == group.Max(y => y.Fileno)))
.ToList();
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()});
I am trying to get an average of occurrences of a string in a list.
Basically I am trying to get the most common occurring string in a list of about 4 options.
So for instance in this example
List<string> lMyList = new List<string>();
lMyList.Add("One");
lMyList.Add("One");
lMyList.Add("Two");
lMyList.Add("Two");
lMyList.Add("Two");
lMyList.Add("Three");
lMyList.Add("Three");
I want to get "Two" returned to me...
Any ideas?
You can use LINQ:
list.GroupBy(s => s).OrderByDescending(g => g.Count()).First()
string most = lMyList.GroupBy(x => x)
.Select(g => new {Value = g.Key, Count = g.Count()})
.OrderByDescending(x=>x.Count).First();
for finding average do:
list.GroupBy(x => x).Average(x=>x.Count())
for finding max do:
var max = groups.OrderbyDescending(x=>x.Count()).FirstOrDefault();
I have a text file stored as a string variable. The text file is processed so that it only contains lowercase words and spaces. Now, say I have a static dictionary, which is just a list of specific words, and I want to count, from within the text file, the frequency of each word in the dictionary. For example:
Text file:
i love love vb development although i m a total newbie
Dictionary:
love, development, fire, stone
The output I'd like to see is something like the following, listing both the dictionary word and its count. If it makes coding simpler, it can also only list the dictionary word that appeared in the text.
===========
WORD, COUNT
love, 2
development, 1
fire, 0
stone, 0
============
Using a regex (eg "\w+") I can get all the word matches, but I have no clue how to get the counts that are also in the dictionary, so I'm stuck. Efficiency is crucial here since the dictionary is quite large (~100,000 words) and the text files are not small either (~200kb each).
I appreciate any kind help.
You can count the words in the string by grouping them and turning it into a dictionary:
Dictionary<string, int> count =
theString.Split(' ')
.GroupBy(s => s)
.ToDictionary(g => g.Key, g => g.Count());
Now you can just check if the words exist in the dictionary, and show the count if it does.
var dict = new Dictionary<string, int>();
foreach (var word in file)
if (dict.ContainsKey(word))
dict[word]++;
else
dict[word] = 1;
Using Groovy regex facilty, i would do it as below :-
def input="""
i love love vb development although i m a total newbie
"""
def dictionary=["love", "development", "fire", "stone"]
dictionary.each{
def pattern= ~/${it}/
match = input =~ pattern
println "${it}" + "-"+ match.count
}
Try this. The words variable is obviously your string of text. The keywords array is a list of keywords you want to count.
This won't return a 0 for dictionary words that aren't in the text, but you specified that this behavior is okay. This should give you relatively good performance while meeting the requirements of your application.
string words = "i love love vb development although i m a total newbie";
string[] keywords = new[] { "love", "development", "fire", "stone" };
Regex regex = new Regex("\\w+");
var frequencyList = regex.Matches(words)
.Cast<Match>()
.Select(c => c.Value.ToLowerInvariant())
.Where(c => keywords.Contains(c))
.GroupBy(c => c)
.Select(g => new { Word = g.Key, Count = g.Count() })
.OrderByDescending(g => g.Count)
.ThenBy(g => g.Word);
//Convert to a dictionary
Dictionary<string, int> dict = frequencyList.ToDictionary(d => d.Word, d => d.Count);
//Or iterate through them as is
foreach (var item in frequencyList)
Response.Write(String.Format("{0}, {1}", item.Word, item.Count));
If you want to achieve the same thing without using RegEx since you indicated you know everything is lower case and separated by spaces, you could modify the above code like so:
string words = "i love love vb development although i m a total newbie";
string[] keywords = new[] { "love", "development", "fire", "stone" };
var frequencyList = words.Split(' ')
.Select(c => c)
.Where(c => keywords.Contains(c))
.GroupBy(c => c)
.Select(g => new { Word = g.Key, Count = g.Count() })
.OrderByDescending(g => g.Count)
.ThenBy(g => g.Word);
Dictionary<string, int> dict = frequencyList.ToDictionary(d => d.Word, d => d.Count);
Here's the scenario:
Given a List of Outputs each associated with an integer based GroupNumber. For each distinct GroupNumber within the List of Outputs starting with the lowest GroupNumber (1). Cycle through that distinct group number set and execute a validation method.
Basically, starting from the lowest to highest group number, validate a set of outputs first before validating a higher groupnumber set.
Thanks,
Matt
There's almost too many ways to solve this:
Here's one for a void Validate method.
source
.GroupBy(x => x.GroupNumber)
.OrderBy(g => g.Key)
.ToList()
.ForEach(g => Validate(g));
Here's one for a bool Validate method.
var results = source
.GroupBy(x => x.GroupNumber)
.OrderBy(g => g.Key)
.Select(g => new
{
GroupNumber = g.Key,
Result = Validate(g),
Items = g.ToList()
})
.ToList();
If you need them as groups:
var qry = source.GroupBy(x=>x.GroupNumber).OrderBy(grp => grp.Key);
foreach(var grp in qry) {
Console.WriteLine(grp.Key);
foreach(var item in grp) {...}
}
If you just need them ordered as though they are grouped:
var qry = source.OrderBy(x=>x.GroupNumber);