Frequency for duplicate items in a list C# - c#

I'm on VS Windows Forms Application and I'm NOT using any other form of coding (e.g. linq) - just the basic style of coding which goes like this;
List<string> brandList = new List<string>();
//brand items are added to the list
//go through list
for(int i = 0; brandList.Count; i++)
{
if(brandList[i]== "BrandName1")
{
//count for that brandName
}
}
What I want to know is how to I get the count for how many times a brand has occurred in the list?
This code will not need to be case sensitive either because it is being read in from a file..

If you don't want/can't use LINQ you could use a Dictionary<string, int>:
Dictionary<string, int> dict = new Dictionary<string, int>();
for(int i = 0; brandList.Count; i++)
{
string brand = brandList[i];
int count = 1;
if(dict.ContainsKey(brand))
count = dict[brand] + 1;
dict[brand] = count;
}
Now you have all brands as key and their counts as value.

I really don't see the problem because your code is already have the solution if I understand correctly the question. You go through the elements, if the current element is the element to count you increment a variable.
const string BRAND = "BrandName1";
int count = 0;
foreach (string brand in brandList)
{
if (string.Compare(brand, BRAND, true))
{
count++;
}
}
Obviously you can use for (int i = 0; i < brandList.Count; i++) and brandList[i] instead of foreach, but it's more like C#.

How about this:
List<string> brandList = new List<string>();
//brand items are added to the list
//sort list to get number of occurences of each entry
brandList.Sort();
var occurences = new List<KeyValuePair<string, int>>();
//go through list
var numBrand = 1;
for (int i = 0; i < brandList.Count-1; i++)
{
if (string.Equals(brandList[i + 1], brandList[i]))
{
numBrand++;
}
else
{
occurences.Add(new KeyValuePair<string, int>(brandList[i], numBrand));
numBrand = 1;
}
}
var highestCount = occurences.OrderBy(o => o.Value).ToList()[0].Key;
It might skip the last entry if that is a single occurences but then that's not the highest anyway.
Would that do the trick for you?

Related

C# - Creating multiple lists based on int in Console

I want to create multiple lists from a given size. Imagining it could look something like this :
int Size = int.Parse(Console.ReadLine());
for (int i = 0; i < Size; i++)
{
List<string> ListName + i = new List<string>();
}
So for example if size = 5 I'd get 5 lists :
ListName0
ListName1
ListName2
ListName3
ListName4
Create a container for the lists outside your loop:
int Size = int.Parse(Console.ReadLine());
List<List<string>> listContainer = new List<List<string>>();
for (int i = 0; i < Size; i++)
{
listContainer.Add(new List<string>());
}
You can access them via the index of the container object. For example listContainer[0] would be the first list<string> in the container.
Here is an example of accessing one of the lists and then accessing a value from said list:
int Size = int.Parse(Console.ReadLine());
List<List<string>> listContainer = new List<List<string>>();
for (int i = 0; i < Size; i++)
{
listContainer.Add(new List<string>());
}
listContainer[0].Add("Hi");
Console.WriteLine(listContainer[0][0]);
the common way is to use a dictionary
var list = new Dictionary<string, List<string>>();
int size = int.Parse(Console.ReadLine());
for (int i = 0; i < size; i++)
list["Name"+i.ToString()] = new List<string>();
how to use
list["Name1"].Add( "hello world");

Two element subset using c#

I am trying to generate a 2-element subset of all the sets in the code.
Eg. if the list contains {1,2,3,4}, 2-element subsets will be {1,2},{1,3},{1,4},{2,3},{2,4},{3,4}.
I am stuck with the logic and cannot go further. Any help will be appreciated.
class Program
{
static List<SortedSet<string>> _items = new List<SortedSet<string>>();
static SortedSet<string> set = new SortedSet<string>();
static void Main(string[] args)
{
int i, j, a, b;
string k;
Console.WriteLine("\n Enter the number of set to be used: ");
i = Convert.ToInt32(Console.ReadLine());
for ( j = 1; j <= i; j++)
{
SortedSet<string> set = new SortedSet<string>();
do
{
Console.WriteLine("Enter first element in set {0}:", j);
k = Console.ReadLine();
if (k != "stop")
set.Add(k);
} while (k != "stop");
_items.Add(set);
}
}
public void DisplayTwoElementSets(List<string> set)
{
foreach (string item in set)
{
GenerateTwoElementSet(setNumber);
}
}
private void GenerateTwoElementSet(int setNumber)
{
SortedSet<string> originalSet = _items[setNumber];
List<SortedSet<string>> twoItemSets = new List<SortedSet<string();
foreach (string item in originalSet)
{
Console.WriteLine(item);
}
}
I'm assuming that the part you are stuck at is the Console.WriteLine(item); spot near the bottom of your code.
Your goal is to create a list of unique pair combinations across a range of values. The simplest way is to use two nested for loops, where the inner loop's index value is dependent on the outer loop's index value.
You can store these sets in Lists or Sets, but the type that will probably be the most appropriate would be the Tuple. A Tuple holds exactly the number of values you specify (in this case, 2) and maintains their order in properties with the naming scheme Item1, Item2, Item3, etc.
(Also note that you are declaring this method within the same class that holds your Main method, so for the sake of sanity, it is best to declare this as static.)
private static List<Tuple<int, int>> GenerateTwoElementSet(int setNumber)
{
List<Tuple<int, int>> set = new List<Tuple<int, int>>();
for (int i = 1; i <= setNumber; i++)
{
for (int j = i + 1; j <= setNumber; j++)
{
set.Add(new Tuple<int, int>(i, j));
}
}
return set;
}
You can get the values from the set like so:
var set = GenerateTwoElementSet(4);
foreach (var tuple in set)
{
Console.WriteLine("{" + tuple.Item1 + "," + tuple.Item2 +"}");
}
// Outputs the following:
// {1,2}
// {1,3}
// {1,4}
// {2,3}
// {2,4}
// {3,4}
EDIT: If you want to make pairs out of an existing list rather than a range of numbers, the logic is still the same. You just use the numbers from the above method as indices for your list.
private static List<Tuple<string, string>> GenerateTwoElementSetFromList(List<string> list)
{
List<Tuple<string, string>> set = new List<Tuple<string, string>>();
for (int i = 0; i < list.Count; i++)
{
for (int j = i + 1; j < list.Count; j++)
{
set.Add(new Tuple<string, string>(list[i], list[j]));
}
}
return set;
}
And you use it like so:
List<string> list = new List<string>
{
"apple",
"pear",
"orange",
"plum"
};
var set = GenerateTwoElementSetFromList(list);
foreach (var tuple in set)
{
Console.WriteLine("{" + tuple.Item1 + "," + tuple.Item2 +"}");
}
// Outputs the following:
// {apple,pear}
// {apple,orange}
// {apple,plum}
// {pear,orange}
// {pear,plum}
// {orange,plum}

Cannot convert from 'string' to 'system.collections.generic.list string'

I have the two list
nested list of string, and
list in string
In index list, I want to add linesOfContentwith a common value and in-between i want to add separate string ":".
For that i write a code, but, I face a problem "cannot convert from 'string' to 'system.collections.generic.list string'". How to solve this.
int common = 10;
List<List<string>> index = new List<List<string>>();
List<int> linesOfContent = new List<int>();
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
linesOfContent.Add(i+":"+common);
}
index.Add(linesOfContent);
}
Expected Output:
index[0][0] = 0:10
index[0][1] = 1:10
index[0][2] = 2:10
...
...
A List of Lists of string should contain Lists of string, not Lists of int.
int common = 10;
List<List<string>> index = new List<List<string>>();
List<string> linesOfContent = new List<string>();
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
linesOfContent.Add(i.ToString() +":"+common.ToString());
}
index.Add(linesOfContent);
}
Each item in your index list is a List<string>. When you try to add an item, it should be a List. However, you're trying to add a string to it, linesOfContent+":"+common is considered a string.
Solution:
Linq's Select Method (aka Projection) can be used to transform each element inside a sequence:
index.Add(linesOfContent.Select(x=> x.ToString() + ":" + common).ToList());
Be aware that the way you're constructing your loops results in some duplicate records.
Here's the code, without the foreach loops, instead it uses Enumerable.Range:
linesOfContent.AddRange(Enumerable.Range(0, 5).Select(i => i.ToString() + ":" + common.ToString()).ToArray());
index.Add(linesOfContent);

Values in a Dictionary are getting replaced by last value in C#

I have a Dictionary type variable where I'm keeping "string" type key and "List " type values.
The problem is, in case of loop all the previous values are getting replaced by the last value.
Why this happens?
List<IWebElement> indicationsElement = ReturnIndicationList();
drugsDB = new List<string>();
for (int i = 0; i < indicationsElement.Count;i++ )
{
string key = indicationsElement[i].Text.ToString();
dt = ZittarPatt.getDrugsByIndication(ClientName, key);
drugsDB.Clear();
for (int k = 0; k < dt.Rows.Count; k++)
{
drugsDB.Add(dt.Rows[k].ItemArray[3].ToString().Trim());
}
drugsByindicationDictionary.Add(key, drugsDB);
}
You're adding the same reference every iteration instead of adding new instance of List<string>.
Every time you use .Clear it clears all the entries at drugsByindicationDictionary which are already the same entry.
Thus, only the last addition to drugsDB will be saved. (No .Clear is used at the end)
You should do the following code:
List<IWebElement> indicationsElement = ReturnIndicationList();
for (int i = 0; i < indicationsElement.Count;i++ )
{
string key = indicationsElement[i].Text.ToString();
dt = ZittarPatt.getDrugsByIndication(ClientName, key);
var drugsDB = new List<string>();
for (int k = 0; k < dt.Rows.Count; k++)
{
drugsDB.Add(dt.Rows[k].ItemArray[3].ToString().Trim());
}
drugsByindicationDictionary.Add(key, drugsDB);
}
Change drugsDB.Clear(); to drugsDB = new List<string>();

Having a new list<> in each for loop iteration

I am trying to having a new list added on every for loop iteration. I have the following code:
for (int i = 0; i < torni.Length; i++)
{
List<string> torni+i = // STUCK HER
}
Listnames should be like torni0, torni1, torni2 ......
Would really appreciate your assistance. Thanks!!
One way of doing this that would be slightly different would be to make a list of lists and then each index would be a discrete list.
You can't dynamically generate variable names in c#
like this:
tornis = new List<List<String>>()
for (int i = 0; i < torni.Length; i++)
{
tornis.append(new List<String>())
}
Alternatively as DanH Points out a dictionary of lists
tornis = new Dictionary<String,List<String>()
for (int i = 0; i < torni.Length; i++)
{
tornis.add("torni" + i, new List<String>())
}
This will give you a dictionary with the keys of the convention you want and a list of lists.
If you need each list only for the duration of a single loop iteration, then you don't need different list names:
for (int i = 0; i < torni.Length; i++)
{
List<string> temporaryList = new List<string>();
// use the list here
}

Categories