Create an array of list - c#

I want to create a array of list which will contain a string and a list of arrays.
example:
I want like this one.
list(0) --- string value list(0) ---list(0) - string value
list(0) ----list(1) - string value
list(1) --- string value list(1) ---list(0) - string value
list(1) ----list(1) - string value
and so on..
how will i declare?
i tried:
List<List<String>> list = new List<List<string>>(); // but it didn't work.
List<string[]> arrayList = new List<string[]>(); // again it didn't work..
is this possible to declare?
if so how?

Isnt this a Dictionary<string, string[]>?
var x = new Dictionary<string, string[]>();
x.Add("string1", new string[] {"a", "b", "c"})
Then you can have a list of that dictionary.
var list = new List<Dictionary<string, string[]>>();
list.Add(x);

Does this work for you?
public class Tree<T> : List<Tree<T>>
{
public Tree(T value) { this.Value = value; }
public T Value { get; set; }
}
It's not an array, but a list, but it's much the same structure.
You can then assign it like this:
var trees = new []
{
new Tree<string>("Branch 1")
{
new Tree<string>("Leaf 1.1"),
new Tree<string>("Leaf 1.2"),
},
new Tree<string>("Branch 2")
{
new Tree<string>("Leaf 2.1"),
new Tree<string>("Leaf 2.2"),
},
};

As I can see in your data structure you've asked for A List containing two List's and all of them are of same string type then you should go with Dictionary. As a List can of of single type and you can add a single value to it at a time. Try Dictionary,
Dictionary<string, string> dictionary = new Dictionary<string, string>();
or if you want a Dictionary containing List of string,
Dictionary<List<string>, List<string>> dictionary = new Dictionary<List<string>, List<string>>();

try this
List<List<String>> str_2d_list = new List<List<String>>();
List<String> l1 = new List<string>();
l1.Add("l1.string1");
l1.Add("l1,string2");
List<String> l2 = new List<string>();
l2.Add("l2.string1");
l2.Add("l2,string2");
str_2d_list.Add(l1);
str_2d_list.Add(l2);

if you want to create an array of a string and a list, use the second way in the code. but if you want a list of list use first way in the code.
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
// an example of list of strings
List<string> names = new List<string>();
names.Add("Mike");
names.Add("Sarah");
List<string> families = new List<string>();
families.Add("Ahmadi");
families.Add("Ghasemi");
// 1st way
List<List<string>> outsideList = new List<List<string>>();
outsideList.Add(names);
outsideList.Add(families);
// 2nd way
Dictionary<string, List<string>> d = new Dictionary<string, List<string>>();
d.Add("first", names);
d.Add("second", families);
// how to access list<list<>>
foreach (List<string> list in outsideList)
{
foreach (string s in list)
Console.WriteLine(s);
}
// how to access list inside dictionary
foreach (List<string> list in d.Values)
{
foreach (string s in list)
Console.WriteLine(s);
}
}
}
}

Related

C# Adding doubles and ints to a list

Noob logic student here.
How do you add doubles and ints to a list? I still have a hard time reading Microsoft's guide.
public static List<string> salesCustomerName = new List<string>();
public static List<string> salesItemDescription = new List<string>();
public static List<double> salesItemPrice = new List<double>();
public static List<int> salesQuantity = new List<int>();
public static void ReadItems() {
// use a StreamReader to read data from items.csv
string filename = "data/items.csv";
if (File.Exists(filename)) {
using (var reader = new StreamReader(filename)){
reader.ReadLine();
while (!reader.EndOfStream) {
var line = reader.ReadLine();
var values = line.Split(",");
salesCustomerName.Add(values[0]);
salesItemDescription.Add(values[1]);
salesItemPrice[2].Add();
salesQuantity.AddInt();
}
}
} else {
Console.WriteLine($"{filename} does not exist");
}
// populate the items lists
SaveItems();
Same as you did with the salesCustomerName but you will need to convert into integer and double and add them.
salesQuantity.Add(Convert.ToInt32(strQuantity));
Similarly for item price, convert to double and add it.

List<KeyValuePair> overrides added values

I am currently facing an issue where I want to add different values to the same Key in a foreach loop.
List<KeyValuePair<string, Dictionary<string, string>>> sysList = new List<KeyValuePair<string, Dictionary<string, string>>>();
Dictionary<string, string> newSystem = new Dictionary<string, string>();
string line1="";
string line2="";
string quit="";
foreach(Worksheet ws in workbook.Worksheets)
{
while(quit != q)
{
newSystem.Clear();
line1 = Console.ReadLine();
line2 = Console.ReadLine();
quit = Console.ReadLine();
}
newSystem.Add(line1, line2);
sysList.Add(new KeyValuePair<string, Dictionary<string, string>>(ws.Name,newSystem));
}
For the first iteration (within while) of the first Worksheet ws everything is fine. If the I choose to do >1 iterations within this Worksheet, there is a new entry added, but the Dictionary values are all the same, f.e.:
syList[0]: "worksheetName","test1","test2"
syList[1]: "worksheetName","test1","test2"
syList[2]: "worksheetName","test1","test2"
If there are several foreach iterations, the names stay the same, but the Dictionary Key and Values added by newSys are the same [AFTER the second foreach iteration]:
syList[0]: "worksheetName1","test1","test2"
syList[1]: "worksheetName1","test1","test2"
syList[2]: "worksheetName1","test1","test2"
syList[3]: "worksheetName2","test1","test2"
syList[4]: "worksheetName2","test1","test2"
Initially I tried using Dictionaries, but could not handle the same keys properly and did not find a proper solution except for using List.
I am very grateful for any help provided.
If there are additional details that you require, please, let me know.
Edit:
desired result (example):
#########: ws.Name, line1, line2
syList[0]: "worksheetName1","ABC","1"
syList[1]: "worksheetName1","DEF","2"
syList[2]: "worksheetName1","ABC","5"
syList[3]: "worksheetName2","ABD","4"
syList[4]: "worksheetName2","ZZZ","1"
In case you don't want to maintain any uniqueness in the keys and just want a flat list, you can use the C#7 tuple syntax to build your list.
List<string> sheetNames = new List<string>() { "worksheetName1", "worksheetName2" };
var sysList = new List<(string SheetName, string line1, string line2)>();
string line1 = string.Empty;
string line2 = string.Empty;
string quit = string.Empty;
foreach (var sheet in sheetNames)
{
while (quit != "E")
{
line1 = Console.ReadLine();
line2 = Console.ReadLine();
quit = Console.ReadLine();
sysList.Add((sheet, line1, line2));
}
quit = string.Empty;
}
Try code below :
List<List<string>> syList = new List<List<string>>() {
new List<string>() {"worksheetName1","test1","test2"},
new List<string>() {"worksheetName1","test1","test2"},
new List<string>() {"worksheetName1","test1","test2"},
new List<string>() {"worksheetName2","test1","test2"},
new List<string>() {"worksheetName2","test1","test2"}
};
Dictionary<string, Dictionary<string, List<string>>> dict = syList
.GroupBy(x => x.First(), y => y)
.ToDictionary(x => x.Key, y => y
.GroupBy(a => a.Skip(1).FirstOrDefault(), b => b.Last())
.ToDictionary(a => a.Key, b => b.ToList()));
//using normal looping
Dictionary<string, Dictionary<string, List<string>>> dict2 = new Dictionary<string, Dictionary<string, List<string>>>();
foreach (List<string> sy in syList)
{
if (dict2.ContainsKey(sy[0]))
{
Dictionary<string, List<string>> tempDict = dict2[sy[0]];
if (tempDict.ContainsKey(sy[1]))
{
tempDict[sy[1]].Add(sy[2]);
}
else
{
List<string> newList = new List<string>() { sy[2] };
tempDict.Add(sy[1], newList);
}
}
else
{
Dictionary<string, List<string>> newDict = new Dictionary<string, List<string>>();
newDict.Add(sy[1], new List<string> { sy[2] });
dict2.Add(sy[0], newDict);
}
}

Create number of new class objects from dictionary count

int proprtyCount = dictionary.Keys.Count;
foreach (KeyValuePair<object, object> pair in dictionary)
{
ClassCustom obj1 =new ClassCustom(pair.Key, pair.Value);
}
I need to create number objects using dictionary.keys.count and pass those objects to some collection class.
i have to pass objects like below to collection (eg.dictionary key count is 3 in this case)
SomeCollection collection =new SomeCollection(obj1,obj2,obj3);
Why don't you assign it to a list?
int proprtyCount = dictionary.Keys.Count;
var classCustomList = new List<ClassCustom>();
foreach (KeyValuePair<object, object> pair in dictionary)
{
classCustomList.Add(new ClassCustom(pair.Key, pair.Value));
}
SomeCollection collection = new SomeCollection(classCustomList);
Have the SomeCollection class initialize a list of type classCustomList in it's constructor.
Update: If it's some sort of collection class, maybe try doing something similar to
int proprtyCount = dictionary.Keys.Count;
var conditions = new PropertyCondition[propertyCount];
int index = 0;
foreach (KeyValuePair<object, object> pair in dictionary)
{
conditions[i] = new PropertyCondition(pair.Key, pair.Value));
index++;
}
var conditionEnabledButtons = new AndCondition(conditions);
There's an overload with type array
Eg.
var conditions = new PropertyCondition[3];
conditions[0] = new PropertyCondition(AutomationElement.IsEnabledProperty, true);
conditions[1] = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button);
var conditionEnabledButtons = new AndCondition(conditions);

How do I make a combobox display a list of dictionaries and act upon the selected value?

C# / Winforms program.
I have the following class which contains my dictionaries:
public class DictionaryInit
{
public Dictionary<int, DictionaryCheckup> C = new Dictionary<int, DictionaryCheckup>()
{
{1000, new DictionaryCheckup {theGrouping="C"}},
{100, new DictionaryCheckup {theGrouping="C"}},
};
}
Where DictionaryCheckup is a class that get;sets; a string theGrouping.
In the class, I would have letters from C to T, and I wanted to display their values within a combo box. This is what I've tried:
var theDictionaries = new DictionaryInit();
List<Dictionary<int, DictionaryCheckup>> Dictionaries = new List<Dictionary<int, DictionaryCheckup>> { theDictionaries.C, etc };
cmbDictionList.DataSource = new BindingSource(Dictionaries, null);
Running this fills the box with [Collection].
The process and desired outcome:
The idea is that, the user first selects a dictionary (C-T) from the combo box and the value gets saved to a variable. I then have the following code that will make use of this:
OFD.ShowDialog();
var theDict = new DictionaryInit();
if (OFD.FileName != null)
{
using (var stream = new StreamReader(File.OpenRead(OFD.FileName)))
{
// Read our JSON from the file
var json = stream.ReadToEnd();
theDict.E = JsonConvert.DeserializeObject<Dictionary<int, DictionaryCheckup>>(json);
var files = new Dictionary<string, Dictionary<int, DictionaryCheckup>>();
}
}
As you can see in my current process, I am explicitly declaring theDict.E. I wish to be able to replace it with a variable I picked up from the combo box earlier, so that I may choose which dictionary I serialize / deserialize.
I want to be able to somehow use my DictionaryInit class as the datasource of the combo box.
The value selected will determine the dictionary I will serialize in a later method.
If all DictionaryCheckup inside DictionaryInit.C have the same letter I would do it like this:
Add Letter property to DictionaryInit
Bind ComboBox to List
Set ComboBox's DisplayMember = "Letter"
Code:
public class DictionaryInit
{
public string Letter { get; private set; }
public DictionaryInit(string letter)
{
this.Letter = letter;
C = new Dictionary<int, DictionaryCheckup>()
{
{1000, new DictionaryCheckup {theGrouping=letter}},
{100, new DictionaryCheckup {theGrouping=letter}},
};
}
public Dictionary<int, DictionaryCheckup> C { get; private set; }
}
var list = new List<DictionaryInit>();
list.AddRange(new[]{new DictionaryInit("C"), new DictionaryInit("D")});
cmbDictionList.DataSource = list;
cmbDictionList.DisplayMember = "Letter";

Get KeyValuePair given Key

Given a String that is a Key contained in Dictionary<String, List<String>>, how do I retrieve the KeyValuePair<String, List<String>> that corresponds to that Key?
The problem with other answers using FirstOrDefault is that it will sequentially search the entire dictionary until it finds a match, and you lose the benefit of having a hashed lookup. It seems more sensible if you really need a KeyValuePair to just build one, like this:
public class Program
{
public static void Main(string[] args)
{
var dictionary = new Dictionary<string, List<string>>
{
["key1"] = new List<string> { "1" },
["key2"] = new List<string> { "2" },
["key3"] = new List<string> { "3" },
};
var key = "key2";
var keyValuePair = new KeyValuePair<string, List<string>>(key, dictionary[key]);
Console.WriteLine(keyValuePair.Value[0]);
}
}
(with credit to David Pine for the original code in his answer).
Here's a fiddle for that: https://dotnetfiddle.net/Zg8x7s
Usually you want the value associated with the key, for example:
Dictionary<String, List<String>> dictionary = GetDictionary();
var value = dictionary["key"];
But you can use Linq to get the entire KeyValuePair:
var dictionary = new Dictionary<string, List<string>>
{
["key1"] = new List<string> { "1" },
["key2"] = new List<string> { "2" },
["key3"] = new List<string> { "3" },
};
var keyValuePair = dictionary.FirstOrDefault(kvp => kvp.Key == "key2");
Console.WriteLine(keyValuePair?.Value[0]); // Prints "2"
Here is a .NET Fiddle.

Categories

Resources