grouping 100 number in array into 4 group in c# [duplicate] - c#

This question already has answers here:
Split a collection into `n` parts with LINQ? [duplicate]
(21 answers)
Closed 6 years ago.
Hi everybody I have an array with 1 to 100 number and I want to group it to four group that each group have 25 number. How can i do it. Thanks
static void Main(string[] args)
{
int[] array = new int[101];
for (int i = 1; i <= 100; i++)
{
array[i] = i; Console.WriteLine(array[i]);
}
var s = array.GroupBy(x => array.Length % 25).Select(d => new { k = d.Key, v = d.OrderBy(f => f) });
foreach (var item in s)
{
Console.WriteLine($"{item.k}");
foreach (var item2 in item.v)
{
Console.WriteLine($"\t{item2}");
}
Console.WriteLine("------------");
}`enter code here`

Your question is vague; there're many ways to group by the array:
int[] array = Enumerable
.Range(1, 100)
.ToArray();
Possible groupings (by index):
int[][] result = array
.Select((item, index) => new {
item = item,
index = index })
.GroupBy(chunk => chunk.index % 4)
.Select(chunk => chunk
.Select(x => x.item)
.ToArray())
.ToArray();
Or
int[][] result = array
.Select((item, index) => new {
item = item,
index = index })
.GroupBy(chunk => chunk.index / 25)
.Select(chunk => chunk
.Select(x => x.item)
.ToArray())
.ToArray();
Or grouping by value
int[][] result = array
.GroupBy(item => item % 4)
.Select(chunk => chunk
.ToArray())
.ToArray();
To print out the result (and test grouping) use string.Join:
string report = string.Join(Environment.NewLine, result
.Select(line => string.Join(" ", line
.Select(item => string.Format("{0,3}", item)))));
Console.Write(report);

Related

How to make an Enumerable Range List of Lists?

I can make a List of chars like this:
List<char> letter = Enumerable.Range(0, 10)
.Select(i => '\0')
.ToList();
And a List of int? like this:
List<int?> number = Enumerable.Range(0, 10)
.Select(i => (int?)i)
.ToList();
And call them by letter[1] = 'a' and number[1] = 5.
How can I make a List (or HashSet) of 10 List<char>'s?
Something like:
List<char> myList = Enumerable.Range(0, 10)
.Select(i => List<char> i)
.ToList();
myList[1], myList[2], myList[3]
I want to loop through and add items to each list.
for (int i = 0; i < 10; i++)
{
myList[i].Add(letter[i]);
}
You can combine your two approaches as follows:
List<List<char>> myList = Enumerable.Range(0, 10)
.Select(i => Enumerable.Range(0, 10).Select(c => '\0').ToList())
.ToList();

How to get the element of array with Max Value?

I'm trying to get the letter of an array that as a max value of a repeated letters on a string.
I have is this:
var AsciiCode = new int[255];
string word= "Hello everybody";
foreach (char c in word)
{
AsciiCode[c]++;
}
MessageBox.Show(string.Format("The max count is:
{0}\nLetter: {1}", AsciiCode.Max(), AsciiCode.ElementAt(//MAX_VALUE_HERE//) ));
A solution with using Linq can be this:
var res =
word.GroupBy(g => g)
.Select(c => new { c.Key, Count = c.Count() })
.OrderByDescending(o => o.Count)
.FirstOrDefault();
C# Demo

How to group by and count similar lists in a List<List<String>>

I have a list of a list of strings:
List<List<String>> pChain;
It might have repeated lists of strings (two list of strings are equal if they have the same strings in the same order). I want to have the count of each distinct list in the main list. I tried:
var results = (from t in pChain
group t by new { t }
into g
select new
{
g.Key,
Count = g.Count(),
}).OrderByDescending(x => x.Count).ToList();
foreach (var v in results)
{
ListViewItem lv = listView2.Items.Add(v.Key.ToString());
lv.SubItems.Add(v.Count + "");
}
But it doesn't group similar list of strings into one list and doesn't count them.
You can use SelectMany + Distinct:
var allDistinctItems = pChain.SelectMany(list => list).Distinct();
If you want the count use int countOfDistinctItems = allDistinctItems.Count();.
If you want a dictionary you could use:
Dictionary<string, int> itemCounts = pChain.SelectMany(list => list)
.GroupBy(item => item)
.ToDictionary(g => g.Key, g => g.Count());
You can check if a list of lists contains an specific list by iterating through its elements and checking if they are SequenceEqual(). You should be able to remove the duplicate lists with this:
for(int i = 0; i < pChain.Count(); i++)
{
// If the amount(Count) of SequenceEqual lists in pChain for the current iteration
// of pChain (pChain[i]) is > 1
if (pChain.Count(l => l.SequenceEqual(pChain[i])) > 1)
pChain.RemoveAt(i);
}
Thus the amount of distinct lists would be:
int count = pChain.Count();
You can put the code above into a single linQ line this way:
pChain.Select((x, y) => new { list = x, Index = y }).ToList()
.ForEach(l1 => {
if (pChain.Count(l2 => l2.SequenceEqual(l1.list)) > 1)
pChain.RemoveAt(l1.Index);
});
I tried Aggregate function to join the strings of the inner list to a string resulted from concatenating them. Then applied the GroupBy to this list.
Dictionary<string, int> itemCounts =
pChain.Select(list => list.Aggregate((i, j) => j + '/' + i))
.GroupBy(item => item).OrderByDescending(x => x.Key)
.ToDictionary(g => g.Key.ToString(), g => g.Count());
foreach (var v in itemCounts)
{
ListViewItem lv = listView2.Items.Add(v.Key.ToString());
lv.SubItems.Add(v.Value + "");
}

How to convert IEnumerable<IEnumerable<IGrouping<int,string>>> to IEnumerable<IEnumerable<string>>

I'm trying to partition some comma separated lines into groups of size 2 at max.
How can i convert the collection of groups to list of lists as below?
I expect the partitions to be 3 first and then 4 after grouping.
List<string> chunk = new List<string>()
{
"a,b,c",
"a,d,e",
"b,c,d",
"b,e,d",
"b,f,g",
"e"
};
var partitons = chunk.GroupBy(c => c.Split(',')[0], (key, g) => g);
var groups = partitons.Select(x => x.Select((i, index) => new { i, index }).GroupBy(g => g.index / 2, e => e.i));
IEnumerable<IEnumerable<string>> parts = groups.Select(???)
This is what I wanted
var parts = groups.SelectMany(x => x).Select(y => y.Select(z => z));
Try this:
partitons = groups.Select(x => x.SelectMany(y => y));
I get this:

Make every string unique by appending counter

I have a list of string and I want to make every string in that list unique by appending a number at the end of it. Also, it is case insensitive, so "apple" should be assumed the SAME as "Apple" or "apPlE"
For example:
List<string> input = new List<string>();
input.Add("apple");
input.Add("ball");
input.Add("apple");
input.Add("Apple");
input.Add("car");
input.Add("ball");
input.Add("BALL");
Expected output:
"apple", "ball", "apple2", "Apple3", "car", "ball2", "BALL3"
I need help to develop the logic to produce the output. Thank you.
Edited: I CANNOT have 0 and 1, the repeated string must start with 2, 3, 4...
var newList = input.GroupBy(x => x.ToUpper())
.SelectMany(g => g.Select((s, i) => i == 0 ? s : s + (i+1)))
.ToList();
var str = String.Join(", ", newList);
EDIT
var newList = input.Select((s, i) => new { str = s, orginx = i })
.GroupBy(x => x.str.ToUpper())
.Select(g => g.Select((s, j) => new { s = j == 0 ? s.str : s.str + (j + 1), s.orginx }))
.SelectMany(x => x)
.OrderBy(x => x.orginx)
.Select(x => x.s)
.ToList();

Categories