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 a list something like that
var x = new List<string>{"A","B","C","D","E","F"};
I want to group it in doubles like that
1-A
1-B
2-C
2-D
3-E
3-F
What my solution is
var result = new Dictionary<int, List<string>>();
var sequence = 1;
var groupList = new List<string>();
for (var i = 0; i < x.Length ; i++)
{
groupList.Add(x[i]);
if ((i + 1)%2 == 0)
{
result.Add(sequence, groupList);
groupList = new List<string>();
sequence++;
}
}
return result;
I am looking for alternative (better) ways to get same result.
Here is another way:
int numPairs = 3;
char[] abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
var dict = new Dictionary<int, char[]>();
for (int i = 1, k=1; i <= numPairs && k<abc.Length; i++, k+=2)
{
dict.Add(i, new char[] { abc[k - 1], abc[k] });
}
return dict;
This will do the same.
var y = x.GroupBy(i =>Convert.ToInt32((x.IndexOf(i) + 1.1) * 0.5));
I think this is a readable Linq solution:
var result = x
.Select((value, index) => new { value, index })
.GroupBy(arg => arg.index / 2 + 1, arg => arg.value);
The Select projects the value with its index into an anonymous type, and the GroupBy groups by the index.
If you need the groupings in a Dictionary like in your question, use ToDictionary:
var dictionary = result.ToDictionary(
grouping => grouping.Key,
grouping => grouping.ToList());
Related
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 2 years ago.
Improve this question
I have the code as below
var searchValues = new double[] { 21.1, 21.65, 22.2, 22.75, 23.3, 23.85, 24.4, 24.95, 25.5, 26.05, 26.6, 27.15, 27.7, 28.25, 28.8, 29.35, 29.9, 30.45, 31, 31.55, 32.1, 32.65, 33.2, 33.75, 34.3, 34.85, 35.4, 35.95 };
var searchValue = 22;
double nearest = searchValues .Select(p => new { Value = p, Difference = Math.Abs(p - searchValue ) })
.OrderBy(p => p.Difference)
.First().Value;
This code returns me 22.2 . However i want the result to be the smallest value close to 22, i.e it will be 21.65. How do i achieve this? I am relatively new to C# and would appreciate some help.
As per your expected output you are trying to find closed value which is less than searchValue. Try below
var searchValues = new double[] { 21.1, 21.65, 22.2, 22.75, 23.3, 23.85, 24.4, 24.95, 25.5, 26.05, 26.6, 27.15, 27.7, 28.25, 28.8, 29.35, 29.9, 30.45, 31, 31.55, 32.1, 32.65, 33.2, 33.75, 34.3, 34.85, 35.4, 35.95 };
var searchValue = 22;
double nearest = searchValues
.Where(x => x <= searchValue) //Filter all values which are less than or equal to searchValue
.OrderBy(y=> y) //Order resultant values by ascending order
.LastOrDefault(); //Get the max value from an array.
Console.WriteLine(nearest == 0 && searchValue > 0 ? "Invalid Input" : $"Nearest Value : {nearest}");
.net Fiddle
You can just apply Math.Round() in difference.
var searchValues = new double[] { 21.1, 21.65, 22.2, 22.75, 23.3,
23.85, 24.4, 24.95, 25.5, 26.05, 26.6, 27.15, 27.7,
28.25, 28.8, 29.35, 29.9, 30.45, 31, 31.55, 32.1,
32.65, 33.2, 33.75, 34.3, 34.85, 35.4, 35.95 };
var searchValue = 22;
double nearest = searchValues.Select(p => new { Value = p, Difference
= Math.Round(Math.Abs(p - searchValue)) })
.OrderBy(p => p.Difference)
.First().Value;
Console.WriteLine(nearest);
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 6 years ago.
Improve this question
I have a dictionary like this.
var dictionary = new Dictionary<string, int>();
dictionary.Add(string, int);
....
....
To get the key of the highest value of a dictionary in c#, I wrote as below.
String maxKey = dictionary.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;
Currently I get below result using above code.
In Case 1, maxKey is "BBB"
dictionary => [0] {["AAA",0]]
[1] {["BBB",1]]
[2] {["CCC",0]]
In Case 2, maxKey is "BBB"
dictionary => [0] {["AAA",1]]
[1] {["BBB",1]]
[2] {["CCC",0]]
In Case 3, maxKey is "CCC"
dictionary => [0] {["AAA",0]]
[1] {["BBB",0]]
[2] {["CCC",0]]
If there is no highest value in a dictionary (if the highest value found more than one time, it's not mean as "max value") , I want to return null or "".
If there is highest value in a dictionary, I want to return key of the highest value.
Can anybody tell me a better way to do this?
You could do something like this.
var maxKey = dictionary.Aggregate((l, r) => l.Value > r.Value ? l : r);
if(dictionary.Values.Where(x=>x == maxKey.Value).Count() >1)
{
...
return null;
}
return maxKey.Key;
Write another line.
var maxkv = dictionary.Aggregate((l, r) => l.Value > r.Value ? l : r);
var maxKey = dictionary.Where(k => k.Value == maxkv.Value).Take(2).Count() > 1 ? null : maxkv.Key;
This will throw exception if your dictionary is empty so do check for length before this if necessary.
if(dictionary.Count == 0) return; // or some guard like this.
If your dictionary is not empty then you will always have at least one item to take. try to take another item (Take(2)) so if count becomes 2 means there are two or more equal keys with max value.
You can use GroupBy to group the items based on their Value, then get the Group with highest value and check for Items Count
var Dictionary = new Dictionary<string, int>();
int? maxValue = null;
var MaxGroup = Dictionary.GroupBy(a => a.Value).OrderBy(a=>a.Key).First();
if (MaxGroup.Count() == 1)
{
maxValue = MaxGroup.Key;
}
You can use this code:
var dictionary = new Dictionary<string, int> {{"AAA", 1},{"BBB", 0}, {"CCC", 1}};
int maxValue = dictionary.Values.Max();
var maxKVs = dictionary.Where(kv => kv.Value == maxValue);
string keyMax = null;
if (maxKVs.Count() == 1)
{
keyMax = maxKVs.First().Key;
}
else
{
// Multiple items with value equals to max
}
It will store the max value of the dictionary then count how many items have the same value and assign keyMax if only one item have this value.
If you want to browse the dictionary only once, use this foreach:
var dictionary = new Dictionary<string, int> {{"AAA", 1},{"BBB", 0}, {"CCC", 1}};
int maxValue = Int32.MinValue;
string maxKey = null;
foreach (KeyValuePair<string, int> keyValuePair in dictionary)
{
if (keyValuePair.Value > maxValue)
{
maxValue = keyValuePair.Value;
maxKey = keyValuePair.Key;
}
else if (keyValuePair.Value == maxValue)
{
maxKey = null; // not max, reset key
}
}
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 7 years ago.
Improve this question
I am trying to get the count for the most common duplicate item in a list.
So far, I have:
List<string> brandList = new List<string>();
which contains 5 different soft drink brands, and the count is 100. I need to find out which brand has the most duplicates in the list and count how many duplicates there are.
Presuming that your pseudo code actually was:
List<Brand> brandList=new List<Brand>();
// fill list
and your Brand class either overrides Equals+getHashCode or has a property like BrandID which is the identifier. N youow want to get the count of the most popular brand, you can use LINQ:
var mostPopularBrand = brandList.GroupBy(b => g.BrandID)
.OrderByDescending(g => g.Count())
.Select(g => new { BrandID = g.Key, Count = g.Count()})
.First();
Console.WriteLine("Most poular brand: {0} Count: {1}",
mostPopularBrand.BrandID, mostPopularBrand.Count);
Update: If it's actually a List<string>(question was edited):
var mostPopularBrand = brandList.GroupBy(str => str)
.OrderByDescending(g => g.Count())
.Select(g => new { Brand = g.Key, Count = g.Count()})
.First();
Your code doesn't compile. Providing that you mean List<String> as a storage of brands:
var ListbrandList = new List<String>() {
"Cola",
"Juice",
"Cola",
"Water",
"Milk",
"Water",
"Cola",
};
var result = ListbrandList
.GroupBy(item => item)
.Select(item => new {
Name = item.Key,
Count = item.Count()
})
.OrderByDescending(item => item.Count)
.ThenBy(item => item.Name);
String report = String.Join(Environment.NewLine, result
.Select(item => String.Format("{0} appears {1} time(s)", item.Name, item.Count)));
you'll have report as
Cola appears 3 time(s)
Water appears 2 time(s)
Juice appears 1 time(s)
Milk appears 1 time(s)
var result = brandList
.Distinct()
.GroupJoin(brand,
k => k,
b => b,
(k, b) => new { BrandName = k, Count = b.Count() });
// An usage could be...
foreach (var r in result)
{
Debug.WriteLine("{0} Brand has {1}", r.BrandName, r.Count);
}
Without LinQ:
var result = new Dictionary<string, int>();
foreach (var brand in brandList)
{
if (!result.ContainsKey(brand))
{
var count = brandList.FindAll(x => x.Equals(brand)).Count;
result.Add(brand, count);
}
}
foreach (var r in result)
{
Console.WriteLine("{0} Brand has {1}", r.Key, r.Value);
}
You can try to do group using LINQ by Elements and calculate count
var groupedList = from l in ListbrandList
group l by l into grp
select new { key = grp.Key, cnt = grp.Count()};
Then you will have group by key (Element) and value (Count)
Something like this maybe:
var res = brandList.GroupyBy(x => x)
.Select(x => new {Key = x.Key, Count = x.Count});
Now you have a list containing the actual drink-number and the count for this number.
EDIT: Getting the brand with most count is now easy, e.g. by using:
var mostPopular = res.Single(x => x.Count == res.Max(y => y.Count));
EDIT2: Without LINQ the following might work, which is way longer and more complicated:
// get the count for every brand
Dictionary<string, int> res = new Dictionary<string, int>();
foreach(var x in brands)
{
if (!res.ContainsKey(x)) res[x] = 0;
res[x]++;
}
// now get the max count
int currentMax = 0;
string key = "";
foreach (var kv in res)
{
if (kv.Value > currentMax)
{
currentMax = kv.Value;
key = kv.Key;
}
}
Now the key should contain the brand with highest Count.
To count element with specific value in a list use :
int quantity = lst.Count(r => r == "Cola");
Example :
List<string> lst = new List<string>()
{
"Sprite",
"Cola",
"Sprite",
"Sprite",
"Cola",
"Sprite",
"Sprite",
"Cola",
"Pepsi",
"Sprite",
"Pepsi",
"Sprite",
};
string[] popularBrands = { "Cola", "Pepsi" };
int[] quantities = new int[popularBrands.Length];
for (int i = 0; i < popularBrands.Length; i++)
{
quantities[i] = lst.Count(r => r.ToUpper() == popularBrands[i].ToUpper());
Console.WriteLine("{0} : {1}", popularBrands[i], quantities[i]);
}
Output
Cola : 3
Pepsi : 2
P.S.
About this code r => r.ToUpper() == popularBrands[i].ToUpper() :
r is variable that holds a value from our list (that are taken one by one). We also use ToUpper() to make sure that our check is case insensitive.
So we basically loop through the collection taking values out of it one by one. Each time we put value to r variable and check if this variable satisfies condition. If so - we count it, if not - we just move to next value.
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 8 years ago.
Improve this question
I have an array: options[15,12,52,a,12,15,abc,15] and I need to count options.
Example:
counts[15]:3 or counts[12]:2 ...
I need this in C#. How can I do this?
Thank you for your answers. My solution is here:
Dictionary<object, int> counts = new Dictionary<object, int>();
for (var t = 0; t < voters_options.GetLength(0); t++) {
if (voters_options[t] != null) {
if (!counts.ContainsKey(voters_options[t]))
counts[voters_options[t]] = 1;
else
counts[voters_options[t]] = 1 + counts[voters_options[t]];
}
}
For C# begginer:
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
object[] options = { 15, 12, 52, "a", 12, 15, "abc", 15 };
Dictionary<object, int> counts = new Dictionary<object, int>();
for (var t = 0; t < options.GetLength(0); t++)
{
if (!counts.ContainsKey(options[t]))
counts[options[t]] = 1;
else
counts[options[t]] = 1 + counts[options[t]];
}
foreach (var entry in counts)
Console.Out.WriteLine("Key: " + entry.Key + "; Count: " + entry.Value.ToString());
}
}
}
Results are:
Key: 15; Count: 3
Key: 12; Count: 2
Key: 52; Count: 1
Key: a; Count: 1
Key: abc; Count: 1
You can use LINQ grouping:
string[] options = { "15", "12", "52", "a", "12", "15", "abc", "15" };
var groupedOptions = options.GroupBy(o => o)
.ToDictionary(g => g.Key, g => g.Count());
foreach (var groupedOption in groupedOptions)
Console.WriteLine("{0} : {1}", groupedOption.Key, groupedOption.Value);
Try this with linq in c#:
var groups = arr1.GroupBy(item => item);
foreach (var group in groups)
{
Console.WriteLine(string.Format("{0} occurences of {1}", group.Count(), group.Key);
}
Counting occurrences in Array
Here's a traditional approach.
var options = new [] {"15","12","52","a","12","15","abc","15"};
Dictionary<string, int> counts = new Dictionary<string, int>();
foreach(var t in options)
{
if(counts.ContainsKey(t))
counts[t]++;
else
counts[t] = 1;
}
You can use a dictionary to count the elements.
public ConcurrentDictionary<string, int> CountOptions(int[] options)
{
ConcurrentDictionary<string, int> counts = new ConcurrentDictionary<string, int>();
for (var t = 0; t < options.Length; t++)
{
counts.AddOrUpdate(options[t].ToString(), 1, (k, v) => v + 1);
}
return counts;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have this code
var result = from row in DTgraph.AsEnumerable()
group row by row.Field<string>("Campaign") into grp
select new
{
Campaign = grp.Key,
Count = grp.Count(),
SL = grp.Sum(s => s.Field<Decimal>("Inb.ServiceLevel"))
};
Where the DTgraph is a DataTable
I want to make loop on result. How please?
You can use foreach:
foreach (var item in result)
{
//Your code here
}
Or for to know the index. But you have to add .ToList() at the end of your LINQ:
var result = (from row in DTgraph.AsEnumerable()
group row by row.Field<string>("Campaign") into grp
select new
{
Campaign = grp.Key,
Count = grp.Count(),
SL = grp.Sum(s => s.Field<Decimal>("Inb.ServiceLevel"))
}).ToList();
for (int i = 0; i < result.Count(); i++)
{
//Your code here
//Now you can do result[i].Something
}
Here is a loop:
foreach (var item in result)
{
//your logic to each item of loop
}