How can I store data from 2 columns (from a database) in a List
List<string> _items = new List<string>();
Any help is appreciated
You create a class that will represent a row with 2 columns:
public class Foo
{
// obviously you find meaningful names of the 2 properties
public string Column1 { get; set; }
public string Column2 { get; set; }
}
and then you store in a List<Foo>:
List<Foo> _items = new List<Foo>();
_items.Add(new Foo { Column1 = "bar", Column2 = "baz" });
Use a tuple struct like KeyValuePair
List<KeyValuePair<string, string>> _items = new List<KeyValuePair<string, string>>();
_items.Add(new KeyValuePair<string, string>(foo, bar));
I would use a class
List<MyDataClass> _items = new List<MyDataClass>();
public class MyDataClass
{
public string Value1 { get; set; }
public string Value2 { get; set; }
}
You can either create a new class to hold the data, Or you could use the built in Tuple<> class. http://msdn.microsoft.com/en-us/library/system.tuple.aspx
Also if one of the columns contains a unique ID of some sort, you could also consider using a Dictionary<>.
It's about how to retrieve the data from the new two columns list
List<ListTwoColumns> JobIDAndJobName = new List<ListTwoColumns>();
for (int index = 0; index < JobIDAndJobName.Count;index++)
{
ListTwoColumns List = JobIDAndJobName[index];
if (List.Text == this.cbJob.Text)
{
JobID = List.ID;
}
}
I know this question is pretty old and by now you probably got your answer and have figured out what you need but I wanted to add something that might help someone in the future.
The best current answer is frankly from #csharptest.net but it has a serious performance drawback and so here is my approach a la his answer based on a suggestion to use Dictionary<TKey, TValue>
private Dictionary<string, string> _items = new Dictionary<string, string>();
// if you need to check to see if it exists already or not
private void AddToList(string one, string two)
{
if (!_items.ContainsKey(one))
_items.Add(one, two);
}
// you can simplify the add further
private void AddToList(string one, string two)
{
_items[one] = two;
// note if you try to add and it exists, it will throw exception,
// so alternatively you can wrap it in try/catch - dealer's choice
}
you can also make array of list
List<string> [] list= new List<String> [];
list[0]=new List<string>();
list[1]=new List<string>();
list[0].add("hello");
list[1].add("world");
You could do this:
List<IList<string>> cols = new List<IList<string>>();
You can set how many columns you want.
cols.Add(new List<string> { "", "", "","more","more","more","more","..." });
Related
I need a class that can work with string properties to store data on a structured (class) list but at the same type to have a way to return an index that acts as the order I need to set up my data.
the class can be something like:
public class MyClass
{
public int int1 = 0;
public int int2 = 0;
public int int3 = 0;
public int int4 = 0;
public string string1 { get; set; }
public string string2 { get; set; }
public string string3 { get; set; }
public string string4 { get; set; }
}
then I can use my class to store the data in the class structured format:
string fileName = #"C:\Mylocation\MyTextFileToRead.txt"; //tab delimeted file
Encoding fileEncoding = Encoding.ASCII;
List<MyClass> myDataList = new List<MyClass>();
List<string> simpleData = File.ReadAllLines(fileName, fileEncoding).ToList();
MyClass index = new MyClass();
foreach (var line in simpleData)
{
var lineSplit = line.Split('\t');
MyClass myClassElement = new MyClass
{
string1 = lineSplit[index.int1],
string2 = lineSplit[index.int2],
string3 = lineSplit[index.int3],
string4 = lineSplit[index.int4],
};
myDataList.Add(myClassElement);
}
I use the index to map each property from the text file and then to store each filed values in the corresponding string property.
I do not wish to use object types and have the properties to return a string value and cast it as (int) for the index. I was advised not to use objects as much as possible.
The use of Const fields did not work for the index unless I use the type name of the class (instead an instance of the class), but I don't know if it helps or if this is a better programming option.
I'm not sure if there is a better way of doing this, but would be very welcome with relevant feedback.
To return two diffrent types from one function you can use the way that was introduce in C# 7.3
It works like this:
public (int, string) MyFunc()
{
//do something
return (VarThatInt, VarThatString);
}
//and in main class u call it like this:
(varInt, varString) = MyFunc();
using KeyValuePair to store one property and index, use list of KeyValuePair to store one line , and use dic Dictionary to store file .
List<int> orderIndexList = new List<int> { 2, 1, 4, 0 };
Dictionary<int, List<KeyValuePair<int, string>>> data = new Dictionary<int, List<KeyValuePair<int, string>>>();
int lineNumber = 0;
foreach (var line in simpleData)
{
var lineSplit = line.Split('\t');
List<KeyValuePair<int, string>> listLine = new List<KeyValuePair<int, string>>();
orderIndexList.ForEach(index => listLine.Add(new KeyValuePair<int, string>(index, lineSplit[index])));
data.Add(++lineNumber, listLine);
}
return data;
Return a class that has the two desired outputs. You can even return a third variable to tell the receiving code, which output to use.
public myClass{
String TextValue;
int NumberValue;
bool IsReturnString;
}
You would return an object of myClass.
How can we create a list of objects in C# and acces them by a specific field inside this object?
For example take this object:
class Section
{
public string Name { get; }
public long Size { get; }
public Section(string name, long size)
{
Name = name;
Size = size;
}
}
I would like to create a list of these objects which I can access by Section.Name.
I can create a dictionary like:
private static readonly Dictionary<string, Section> validSections = new Dictionary<string, Section>
{
{ "section-a", new Section("section-a", 1) },
{ "section-b", new Section("section-b", 2) },
{ "section-c", new Section("section-c", 3) },
{ "section-d", new Section("section-d", 4) },
};
But as you see, I have to declare the section name twice, which looks inelegant. Is there a more elegant way?
But as you see, I have to declare the section name twice, which looks
inelegant. Is there a more elegant way?
To avoid repetitve typing you can create dictionary from collection of sections via ToDictionary call:
private static readonly Dictionary<string, Section> validSections = new[] {
new Section("section-a", 1),
new Section("section-b", 2),
new Section("section-c", 3),
new Section("section-d", 4)
}.ToDictionary(s => s.Name);
If this is not time critical then you can use List<Section> list = new ArrayList<Section>(); and store data in it.
Later you can use LINQ to query based on name .where(x=>x.Name=="somename")
First of all your Model class can look like:
class Section
{
public string Name { get; set; }
public long Size { get; set; }
}
You don't need the Name twice so you can just create a list:
private static List<Section> myList = new List<Section>();
myList.add(new Section {Name = "section-a", Size = 1});
// do this for all the sections ...
Then as other answers suggest you can use LINQ:
myList.Single(s => s.Name == "section-a");
Will simply return the single element where the name is "section-a".
Read more about LINQ here: https://msdn.microsoft.com/en-us/library/bb308959.aspx
You could write a function that takes a list of sections and returns the corresponding dictionary. Something like:
public static Dictionary<string, Section> SectionDictionary(List<Section> sections) {
var dict = new Dictionary<string, Section>();
foreach (var section in sections)
dict.Add(section.Name, section);
return dict;
}
You can just access the elements using LINQ:
var list = ...;
var el = list.FirstOrDefault(o => o.Name = nameValue);
Or you can create a (collection) class that implements your own indexer / getter logic. E.g. (pseudocode)
public class MyCollection : Collection<Section>
{
public Section this[string nameValue]
{
get
{
return this.FirstOrDefault(o => o.Name == nameValue);
}
}
}
Then the usage is:
var coll = new MyCollection() ....;
var el = coll["Some name"];
I am unsure whether this is possible with an ArrayList or a Dictionary or whether it would be something else, if so I wonder where you could point me in the right direction...
Can you have an ArrayList with Multiple Values i.e.
ArrayList weather = new ArrayList();
weather.Add("Sunny", "img/sunny.jpg");
weather.Add("Rain", "img/Rain.jpg);
To then assign to controls like below.
if (WeatherValue = 0)
{
Label1.Text = weather[0].ToString;
Image1.ImageUrl = weather[0].ToString;
}
Or can I do this with a Dictionary
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("Cloudy", "../img/icons/w0.png"); //[0]
dict.Add("Rain", "../img/icons/w1.png"); //[1]
Label1.Text = dict[0].VALUE1; //So this would get Cloudy
Image.ImageUrl = dict[0].VALUE2; //This would get ../img/w0.png
How do you call the values of a dictionary separately using [0], and [1] ? etc
There's no reason to still use ArrayList, use the System.Collections.Generic.List<T>-class. Then you keep compile time safety and you don't need to cast everything.
In this case you should create a custom class:
public class Weather
{
public double Degree { get; set; }
public string Name { get; set; }
public string IconPath { get; set; }
public override string ToString()
{
return Name;
}
}
Then you can use this readable and maintainable code:
List<Weather> weatherList = new List<Weather>();
weatherList.Add(new Weather { Name = "Sunny", IconPath = "img/sunny.jpg" });
weatherList.Add(new Weather { Name = "Rain", IconPath = "img/Rain.jpg" });
if (WeatherValue == 0) // whatever that is
{
Label1.Text = weatherList[0].Name;
Image1.ImageUrl = weatherList[0].IconPath;
}
Update: according to your edited question. A dictionary doesn't make much sense because you can't access it via index(it has no order) but only via key. Since that would be the weather-name you have to know it beforehand. But it seems that you don't have it.
So either loop all key-value pairs in the dictionary and use the key for the name and the value for the path or simply use a real class which would be much better.
If you don't want to create a class there's only one thing that comes to my mind, the Tuple:
List<Tuple<string, string>> weatherList = new List<string, string>();
weatherList.Add(Tuple.Create("Sunny", "img/sunny.jpg"));
weatherList.Add(Tuple.Create("Rain", "img/Rain.jpg"));
if (WeatherValue == 0) // whatever that is
{
Label1.Text = weatherList[0].Item1;
Image1.ImageUrl = weatherList[0].Item2;
}
You can use a Dictionary
Dictionary<string, string> weather = new Dictionary<string, string>();
values.Add("Sunny", "img/sunny.jpg");
values.Add("Rain", "img/Rain.jpg");
The simplest way to call element in a dictionnary is using foreach loop
foreach (var pair in weather )
{
Console.WriteLine("{0}, {1}",pair.Key,pair.Value);
}
Is there a List<> similar to a two dimension array? For each entry there is a number and text.
You can use Dictionary<int,String>
Sample:
Dictionary<int,string> samp = new Dictionary<int,string>();
dictionary.Add(1, "text1");
dictionary.Add(2, "text2");
Or, have a custom class which defines your requirement
public class Sample
{
public int Number;
public string Text;
}
Sample:
List<Sample> req = new List<Sample>();
Sample samObj = new Sample();
samObj.Number = 1;
samObj.Text = "FirstText";
req.Add(samObj);
There are many options, I describe some of them for you
use Dictionary<int, string>
Pros: very fast lookup
Cons: you can not have two string with same number, you don't have a List
var list2d = new Dictionary<int, string>();
list2d[1] = "hello";
list2d[2] = "world!";
foreach (var item in list2d)
{
Console.WriteLine(string.Format("{0}: {1}", item.Key, item.Value);
}
use Tuple<int, string>
Pros: very simple and handy tool, you have a List
Cons: Tuples are immutable, you can not change their values once you create them, reduces code readability (Item1, Item2)
var list2d = new List<Tuple<int, string>>();
list2d.Add(new Tuple(1, "hello"));
list2d.Add(Tuple.Create(1, "world");
foreach (var item in list2d)
{
Console.WriteLine(string.Format("{0}: {1}", item.Item1, item.Item2);
}
use a defined class,
Pros: you have a List, very customizable
Cons: you should write more code to setup
public class MyClass
{
public int Number { get; set; }
public string Text { get; set; }
}
var list2d = new List<MyClass>();
list2d.Add(new MyClass() { Number = 1, Text = "hello" });
list2d.Add(new MyClass { Number = 2, Text = "world" });
foreach (var item in list2d)
{
Console.WriteLine(string.Format("{0}: {1}", item.Number, item.Text);
}
Custom class or dictionary are good options, you can also use the Tuple generic...
var i = new List<Tuple<int, string>>();
Dictionary requires that whatever value is used as key must be unique. So not ideal without uniqueness.
A custom class is preferable if you don't mind a little more code and gives you scope to extend later on if you decide you want other data in there.
Tuple is quick and easy but you lose readability and objects can not be edited.
Define a class wih a string and an int property
public class MyClass
{
public string MyStr {get;set;}
public int MyInt {get;set;}
}
then create a list of this class
List<Myclass> myList = new List<MyClass>();
myList.add(new MyClass{MyStr = "this is a string", MyInt=5});
Hope it will help
public class DATA
{
public int number;
public string text;
}
List<DATA> list = new List<DATA>();
The following lists are created in class named "Entities" and they are private.
I would like to return them (and use in another class)what I can do by :
public List<string> getCMList()
{
return exceptionsCM;
}
But if there is 10 list, I have to write a public "get" method for all of them. Is it possible to write a method, that takes a string as an input, and returns that list ?
Should be something similar to ..
public List<string> getList(.....)
{
return exceptionCM;
} //if we call getList(exceptionCM).
exceptionsCM = new List<string>();
exceptionsCM.Add("CM12");
exceptionsCM.Add("CM701");
exceptionsCM.Add("CM901/CM30");
exceptionsCM.Add("CM901K");
exceptionsCM.Add("CM1101");
exceptionsCM.Add("CM1101K");
//List with Multi Mill exceptions, they are included in the new MultiB
exceptionsMultiB = new List<string>();
exceptionsMultiB.Add("Multi650/450");
exceptionsMultiB.Add("Multi660/630");
exceptionsMultiB.Add("Multi650/800");
exceptionsMultiB.Add("Multi650/1000");
//List with Multi Mill exceptions, they are included in the new Multi01
exceptionsMulti01 = new List<string>();
exceptionsMulti01.Add("Multi301");
exceptionsMulti01.Add("Multi601");
exceptionsMulti01.Add("Multi801");
exceptionsMulti01.Add("Multi1001");
You could put them all in a static Dictionary> like that
Dictionary<string, List<string>> ListstDict = new Dictionary<string, List<string>>();
ListsDict.Add("exceptionsCM", exceptionsCM);
...
Then you could write a method like so:
public List<string> GetList(string name)
{
return ListsDict.ContainsKey(name) ? ListsDict[name] : null;
}
But then again, what's the point of this lists being private if you can get them that simply? It would be easier to just declare them as public properties with private setter
public List<string> exceptionsCM { get; private set; }
You can use a Dictionary<K,V> class for this
private Dictionary<string, List<<string>> dictionary =
new Dictionary<string, List<<string>>();
//fill that dictionary
...
//get list from a dictionary by list id
public List getList(string listId)
{
return dictionary[listId];
}
You can put all your lists in a dictionary:
// your code here
dictionary = new Dictionary<string, List<string>>();
dictionary.Add("exceptionsCM", exceptionsCM);
Then the getList method is as simple as:
public List<string> getList(string name)
{
return dictionary[name];
}
Use dictionary and enum.
Using enum for list keys instead of a string makes your code more robust for key renamings. I.e. when you rename MultiB to MultiB1 in Entities class then compiler would not show any errors and warnings about calls to GetList("MultiB"). In case of using enum compiler would show you these errors.
internal class Entities
{
private Dictionary<ListKey, List<string>> _liststDict =
new Dictionary<ListKey, List<string>>
{
{ListKey.Cm, new List<string> {"CM12", "CM701", "CM901/CM30", "CM901K", "CM1101", "CM1101K"}},
{ListKey.MultiB, new List<string> {"Multi650/450", "Multi660/630", "Multi650/800", "Multi650/1000"}},
{ListKey.Multi01, new List<string> {"Multi301", "Multi601", "Multi801", "Multi1001"}}
};
public List<string> GetList(ListKey key)
{
return _liststDict[key];
}
internal enum ListKey
{
Cm,
MultiB,
Multi01
}
}
internal class EntitiesTester
{
public static void Do()
{
Entities entities = new Entities();
Console.Out.WriteLine("CM count = {0}", entities.GetList(Entities.ListKey.Cm).Count);
Console.Out.WriteLine("MultiB count = {0}", entities.GetList(Entities.ListKey.MultiB).Count);
Console.Out.WriteLine("Multi01 count = {0}", entities.GetList(Entities.ListKey.Multi01).Count);
}
}