I am new to C# but i have a background in PHP. Working some basic stuff in C# i came across some odd thing for me. I want to create an array of arrays in C# with string keys that hold another array of string keys. If I had to do this in PHP it whould look like this:
$workers = array("John" => array("salary" => 1000, "bonus" => 200),
"Michal" => array("salary" => 1500, "bonus" => 0)
);
Digging into C# I found some answers like hashtable or dictionary, but it made me more confused.
C# is not like PHP in that it is not loose so you need to declare exactly what the array (hashtable if you want string keys) can hold. Meaning if you wish to have an array of arrays, then the parent array needs to be told that it holds arrays and cannot hold anything else.
This has basicly been answered here:
How to initialize a dictionary containing lists of dictionaries?
Arrays in .NET doesn't have key-value pairs, so you would need to use a different collection for that, like a dictionary.
The closest to your PHP code would be a dictionary of dictionaries, however a dictionary of custom classes work be more in line with how data is handled in C#.
The class:
public class Worker {
public int Salary { get; set; }
public int Bonus { get; set; }
}
The dictionary:
Dictionary<string, Worker> workers = new Dictionary<string, Worker>();
workers.Add("John", new Worker{ Salary = 1000, Bonus = 200 });
workers.Add("Michal", new Worker{ Salary = 1500, Bonus = 0 });
This allows you to locate a worker by name, and then access the properties. Example:
string name = "John";
Worker w = workers[name];
int salary = w.Salary;
int bonus = w.Bonus;
Create a class for your object Worker:
public class Worker
{
public string Name { get; set; }
public double Salary { get; set; }
public int Bonus { get; set; }
public Worker(string name, double salary, int bonus)
{
this.Name = name;
this.Salary = salary;
this.Bonus = bonus;
}
}
Then create a List of workers:
List<Worker> workers = new List<Worker>() {
new Worker("John", 1000, 200),
new Worker("Michal", 1500, 0)
};
What you can do in c# is something like this :
public class Employee
{
public string Name { get; set; }
public double Salary { get; set; }
public int Bonus { get; set; }
public Employee(string name, double salary, int bonus)
{
this.Name = name;
this.Bonus = bonus;
this.Salary = salary;
}
}
And create dictionary :
Dictionary<string, Employee> emps = new Dictionary<string, Employee>();
emps.Add("Michal", new Employee("Michal", 1500, 0));
emps.Add("John", new Employee("John", 1000, 200));
Or sometimes you may wish to use dynamic and anonymous type for our employees rather then strong type (such as Employee) :
var John = new { Salary = 1000, Bonus = 200 };
var Michal = new { Salary = 1500, Bonus = 0 };
var dict = new Dictionary<string, dynamic>()
{
{"John", John},
{"Michal", Michal},
};
Console.WriteLine(dict["John"].Bonus);
output : 200
Related
I have a Class like this:
internal class Name
{
public decimal A { get; set; }
public decimal B { get; set; }
}
internal class Type
{
public string FullyName { get; set; }
public List<Name> Name{ get; set; }
public Type()
{
Name = new List<Name>();
}
}
I can add new Elements to List like this:
internal static List<Type> test = new List<Type>();
var pl = new Type{ Name = "test" };
pl.Name.Add(new Name { A = 0, B = 1 });
test.Add(pl);
But how can I add only new Decimals ("under Name") at a specific index and not to new rows at FullyName? So I want new rows under Names and not new rows under FullyName
I tryed with this, but it is not working
test.Insert(index, 0, 1);
I mean this: (adding new items/elements under "Name" in a specific index FullyName: XY Collection)
FullyName: XY
[0] > Name:
[0] > decimal A: 0
[1] > decimal B: 1
[2]... and so on
FullyName: ZA
[1] > Name:
[0] > decimal A: 0
[1] > decimal B: 1
[2] > decimal A: 3
[3] > decimal B: 4
[4]... and so on
-So, if i Search with Linq the Index of the FullyName XY the Answer is 0: So then i must add new Items/Elements (decimal A / decimal b) under FullyName: XY with the Index of 0 (then under Name adding new Items/Elements), but this is not working with my code for adding new FullyNames or Insert :/
-Hope now is Clearly what i mean :)
thx
First, you need to find the index of which FullyName list you want to add decimals to. You seem to be able to do this with LINQ already. Let's say you store this index in a variable called index.
Now, test[index] will give you a Type object, so test[index].Name will give you a List<Name>, which you can add, insert, remove (or do whatever) pairs of decimals (they're actually Name objects).
To add { A = 0, B = 0 } at to the FullyName list at index index, you do:
test[index].Name.Add(new Name { A = 0, B = 0 });
I think your confusion comes from the naming of your members. You should definitely give better names to them. Maybe:
internal class DecimalPair
{
public decimal A { get; set; }
public decimal B { get; set; }
}
internal class DecimalPairs
{
public string FullName { get; set; }
public List<DecimalPair> Decimals{ get; set; }
}
I need a clear example that shows me how to define a list that has n rows and 4 columns and how to use it. I need a list to save my data like the below image. as you see this could be a dictionary.
You need to create a class with all the above properties
public class Sample
{
public string vocabulary { get; set; }
public string meaning { get; set; }
public int number { get; set; }
public int group { get; set; }
}
and then you can create a List of type Sample,
List<Sample> yourList = new List<Sample>();
You can add items to the list as below
yourList.Add(new Sample { vocabulary = "massive", meaning = "very big", number = 5, group = 15 });
You can access them later like this, if you want the first element,
var result = yourList[0];
this is the easiest and best way of doing it. You need to create a new class and then create new instances of the class and then add it to the list and then use LINQ to get the data out
void Main()
{
var list = new List<myClass>()
list.Add(new myClass() {
Vocabluary = "Vocabluary ",
Meaning = "meaning",
Number = 1,
Group = 2})
}
public class myClass
{
public string Vocabluary { get; set; }
public string Meaning { get; set; }
public int Number { get; set; }
public int Group { get; set; }
}
yes... as Sajeetharan mentioned, with a custom class you can create an any dimensions List. but i don't think you need to think about dimension in C#... it is a bit more high level than that.
just simply create a class and put everything you need in it...
public class CustomClass{
public string d1;
public int d2;
public string d3;
public string d4;
...
//you can easily create a N dimension class
}
to access it and apply it
public void Main(){
List<CustomClass> list = new List<CustomClass>();
CustomClass cc = new CustomClass();
cc.d1 = "v1";
cc.d2 = 0; //v2
list.Add(cc);
//to access it
foreach(CustomClass tmpClass in list)
{
string d1Value = tmpClass.d1;
int d2Value = tmpClass.d2;
}
}
I am making a program that automates data messaging.
I have an Excel sheet that has a Name column, Type Column, and Value Column.
It looks like this:
Name Type Value
Sam A 32
Ben B 65
Sam B 213
max B 23
max C 24
max C 12
Ben C 45
This data is not real, but it is similar to what I am working with.
Note: some of the names do not have certain types.
I have loaded the data in 3 arrays arrName[], arrType[], and arrValue[]
I wish to make the data look like this with a 3D array arrPro[name, type, value]. All the values of the same type should belong to the same name and all the values should be added up together to form a total value.
Load excel data directly to DataSet is the most simple method.
If you do want a 3D array, I suggest
Tuple<string, string, int> as the data holder for each row.
and
List<Tuple<string, string, int>> will hold all your data.
This structure might hold your data
public class MyTypes
{
public string TypeName;
public List<NamesValues> Names;
}
public class NamesValues
{
public string Name;
public List<int> Values;
}
It's not simplier and cleaner to store your data in some List<YourObject> for example:
public class YourObject {
public string Name { get; set; }
public string Type{ get; set; }
public int Value { get; set; }
}
and then count what you want with linq (more less):
List<YourObject> yourObject = "your logic goes here (with whole data)";
List<YourObject> result = from s in yourObject
group s by new { s.Name, s. Type) into r
select new YourObject { Name = r.Name, Type = r.Type, Value = r.Sum(s => s.Value) };
I'm not shure it's exactly what you're looking for (grouping type).
You should use a Dictionary.
public Enum EType
{
A,
B,
C
}
public class PatientData
{
public EType Type { get; set; }
public int Value {get; set; }
}
public class PatientManager
{
private readonly Dictionary<String, List<PatientData>> _patients = new Dictionary<String, List<PatientData>>();
public void AddPatientData(string name, EType type, int value)
{
var patientData = new PatientData
{
Type = type,
Value = value
};
List<PatientData> patientDatas;
if (!dictionary.TryGetValue(name, out patientDatas))
{
patientDatas = new List<PatientData>();
dictionary.Add(key, patientDatas);
}
_patientDatas.Add(patientData);
}
public void LoadData(string[] names, EType[] types, int[] values)
{
var iMax = Math.Min(names.Length, Math.Min(type.Length, values.Length));
for (var i = 0; i < iMax; i++)
{
AddPatientData(names[i], types[i], values[i]);
}
}
}
I have some different data types that i need to do something with in a function. Those data needs to be processed in the function and returned as an object i believe it is called.
This is some not tested code i just wrote here, but i think it displays what im trying to do .. I hope you guys can help me out how to do it.
private void Button_Click(object sender, RoutedEventArgs e)
{
// Here im calling the function which returns data to the object
object thoseProcessedData = SomeTestObject(5, "ABC", SomeOtherThing);
// When returned i want to be able to use the different data like so.
string useItLikeThis = thoseProcessedData.newString;
int numbersLikeThis = thoseProcessedData.newNumber;
}
public object SomeTestObject(int numbers, string letters, AnotherType anothertype)
{
string newString = letters.Substring(0,5);
int newNumber = numbers + 10;
AnotherType newType = anothertype.Something();
return processedData;
}
Please guys dont kill me, if this is a too stupid question. Im still very new to C# ..
If you dont get what im trying to do, please ask! Since my english is not the best i thought this way would be the best to show you what i want..
Create class which holds data you want to pass and return:
public class Data
{
public string Letters { get; set; }
public int Number { get; set; }
public AnotherType Thing { get; set; }
}
Pass it to method:
var data = new Data { Letters = "ABC", Number = 5, Thing = SomeOtherThing };
DoSomething(data);
// here data will have modified values
Thus class is a reference type, all changes to its members inside DoSomething method, will be reflected in your data object reference. So, changes can look like:
public void DoSomething(Data data)
{
data.Letters = data.Letters.Substring(0,5);
data.Number += 10;
data.Thing.Something();
}
Well, you are on the right track (apart from the use of the object keyword/class)!
The object class is the base class of every reference type in C#, it has 3 or 4 functions, and no properties. You will very rarely directly use this class.
The simplest method to do what are you trying to accomplish what you want is to use a Tuple.
This would look like:
public Tuple<string, int, AnotherType> SomeTestObject(
int numbers, string letters, AnotherType anothertype)
{
string newString = letters.Substring(0,5);
int newNumber = numbers + 10;
AnotherType newType = anothertype.Something();
return Tuple.Create(newString, newNumber, newType);
}
If, however, this is going to be used in other places, passed around, etc. you should create a separate object, populate it, and return it.
public MyDataClass SomeTestObject(
int numbers, string letters, AnotherType anothertype)
{
string newString = letters.Substring(0,5);
int newNumber = numbers + 10;
AnotherType newType = anothertype.Something();
return new MyDataClass(newString, newNumber, newType);
}
//Somewhere else, probably another file
public class MyDataClass
{
public string StringData {get; set;}
public int NumberData {get; set;}
public AnotherType ObjectData {get; set;}
public MyDataClass(string myString, int, myNumber, AnotherType myObject)
{
StringData = myString;
NumberData = myNumber;
ObjectData = myObject;
}
}
MSDN For:
Tuple
Object
Create a class to represent that data:
public class ProcessedData
{
public string NewString {get; set;}
public int NewNumber {get; set;}
public AnotherType NewType {get; set;}
}
then populate an instance of that class and return it:
private void Button_Click(object sender, RoutedEventArgs e)
{
// Here im calling the function which returns data to the object
ProcessedData thoseProcessedData = SomeTestObject(5, "ABC", SomeOtherThing);
// now you can access those properties
string useItLikeThis = thoseProcessedData.NewString;
int numbersLikeThis = thoseProcessedData.NewNumber;
}
public ProcessedData SomeTestObject(int numbers, string letters, AnotherType anothertype)
{
ProcessedData processedData = new ProcessedData();
processedData.newString = letters.Substring(0,5);
processedData.newNumber = numbers + 10;
processedData.newType = anothertype.Something();
return processedData;
}
There are mechanisms (anonymous types, dynamic) that would make it possible to dynamically "find" properties at run-time, but defining a class and statically typing the return type is by far safer.
Firstly, your English is fine. Don't worry about that :)
Secondly, what you want to do is just create a class that has those properties on it.
class YourClass {
public string NewString { get; set; }
public int NewNumber { get; set; }
}
Then return an instance of this out of your method:
return new YourClass() {
NewString = letters.Substring(0, 5),
NewNumber = numbers + 10
};
For this you can create a simple class.
public class Data
{
public string NewString { get; set; }
public int NewNumber { get; set; }
}
Then you can return it from a method.
Data ReadData()
{
return new Data {
NewString = CalculateNewString(),
NewNumber = CalclulateNewNumber()
};
}
When you need to return more than one value, you need to create your own class. A class (among other things) encapsulates or "packages together" one or more pieces of data. Here is an example:
public class MyCustomClass {
public int MyCustomInt { get; set; }
public string MyCustomString { get; set; }
public bool MyCustomYesNo { get; set; }
}
This class contains three properties. Properties contain data that can be read from (get) or written to (set). You can now write a function that returns an instance of this property:
public MyCustomClass MyFunction()
{
return new MyCustomClass() {
MyCustomInt = 15, MyCustomString = "Hello World!",
MyCustomYesNo = true
};
}
This function will create a new instance of our MyCustomClass and fill each property with values. And now you can call it like this:
MyCustomClass myVar = MyFunction();
int myInt = myVar.MyCustomInt; // Contains 15
string myString = myVar.MyCustomString; // Contains "Hello World!"
bool myYesNo = myVar.MyCustomYesNo; // Contains true
Now of course, your function can do anything it wishes. I was just providing an example.
Hope this makes sense!
I'm new in C# and my question is, exist on C# arrays like PHP for example
$array = array("name" => array(), "Age" => array());
I want to know if is possible to make an array like that on C#
The closest you can get is a Dictionary<string, string[]>
This gives you the hashtable-type string lookup that returns an array. Note that you need to replace string[] with an array of the type that you want to store.
Lookups then work like this:
var dict = new Dictionary<string, string[]>() {
{ "name", new string[] { "Bob", "Sally" } },
{ "age", new string[] { "twenty four", "twenty three" } }
}
That being said, that's not the C# way of storing data. I'm going to go out on a limb and guess that you're storing a list of people. In C# you're much better off creating a class Person with attributes Name and Age, then populating and holding a list of the people. Example:
public class Person {
public string Name { get; set; }
public int Age { get; set; }
}
var bob = new Person { Name = "Bob", Age = 24 };
var sally = new Person { Name = "Bob", Age = 23 };
var people = new List<Person>() { bob, sally };
You could create your own class
public class People{
public List<string> Names { get; set; }
public List<int> Ages { get; set; }
}
this will allow you to have a class with a list of names and a list of ages. Though I don't think this is really want you want to do or perhaps a better response is: There is a better way to do what you want to do which looks like you want to loop through some names and their RELATED ages.. in which case, you would be better off with something like this:
public class Person{
public int Age { get; set; }
public string Name { get; set; }
}
List<Person> people =new List<Person>{
new Person{Age=20,Name="Bob"},
new Person{Age=25,Name="Sue"},
};
Now you have OBJECTS to work with that hold information in a more relational manner. This will completely avoid having to associate by index.