I have a class of persons and list collection as list contains all the values of person class
such as :
List ilist has 2 values [0]={firstname,lastname} . [1]={firstname2,lastname2}
now when i am iterating into the list i am able to print the list but i want to change the value of some parts of my list e.g in index 1 if i want to change the value of firstname2 to firstname3 i am not able to do it . Can anyone tell me how to print the list and then on that index changing any value of the index , i.e. firstname and secondname variable in the person class so that i can update my values
Thanks
According to the docs on msdn you can use the familiar index operator (like on what you use on arrays). So myList[1].lastname = "new last name"; should do it for you.
Docs are here; http://msdn.microsoft.com/en-us/library/0ebtbkkc.aspx
Keep in mind you need to do bounds checking before access.
I came here whilst searching for access specific index in object array values C# on Google but instead came to this very confusing question. Now, for those that are looking for a similar solution (get a particular field of an object IList that contains arrays within it as well). Pretty much similar to what the OP explained in his question, you have IList person and person contains firstname, lastname, cell etc and you want to get the firstname of person 1. Here is how you can do it.
Assume we have
IList<object> myMainList = new List<object>();
myMainList.Add(new object[] { 1, "Person 1", "Last Name 1" });
myMainList.Add(new object[] { 2, "Person 2", "Last Name 2" });
At first, I though this would do the trick:
foreach (object person in myMainList)
{
string firstname = person[1].ToString() //trying to access index 1 - looks right at first doesn't it??
}
But surprise surprise, C# compiler complains about it
Cannot apply indexing with [] to an expression of type 'object'
Rookie mistake, but I was banging my head against the wall for a bit. Here is the proper code
foreach (object[] person in myMainList) //cast object[] NOT object
{
string firstname = person[1].ToString() //voila!! we have lift off :)
}
This is for any newbie like me that gets stuck using the same mistake. It happens to the best of us.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
List<Person> list = new List<Person>();
Person oPerson = new Person();
oPerson.Name = "Anshu";
oPerson.Age = 23;
oPerson.Address = " ballia";
list.Add(oPerson);
oPerson = new Person();
oPerson.Name = "Juhi";
oPerson.Age = 23;
oPerson.Address = "Delhi";
list.Add(oPerson);
oPerson = new Person();
oPerson.Name = "Sandeep";
oPerson.Age = 24;
oPerson.Address = " Delhi";
list.Add(oPerson);
int index = 1; // use for getting index basis value
for (int i=0; i<list.Count;i++)
{
Person values = list[i];
if (index == i)
{
Console.WriteLine(values.Name);
Console.WriteLine(values.Age);
Console.WriteLine(values.Address);
break;
}
}
Console.ReadKey();
}
}
class Person
{
string _name;
int _age;
string _address;
public String Name
{
get
{
return _name;
}
set
{
this._name = value;
}
}
public int Age
{
get
{
return _age;
}
set
{
this._age = value;
}
}
public String Address
{
get
{
return _address;
}
set
{
this._address = value;
}
}
}
}
More information on your requirement / why you are accessing the list this way might help provide a better recommendation on approach but:
If you want to use your list in this way frequently an Array or ArrayList may be a better option.
That said, if your specific issue is determining the current element you want to change's ID you can use IndexOf(). (note this will loop the array to find the object's position)
If you just know the index of the element, you can reference as both you and #evanmcdonnal describe.
Lists can be modified directly using their indexer.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
var list = new List<Person>
{
new Person
{
FirstName = "Bob",
LastName = "Carlson"
},
new Person
{
FirstName = "Elizabeth",
LastName = "Carlson"
},
};
// Directly
list[1].FirstName = "Liz";
// In a loop
foreach(var person in list)
{
if(person.FirstName == "Liz")
{
person.FirstName = "Lizzy";
}
}
I do not see where you can meet the problem:
public class Persons
{
public Persons(string first, string last)
{
this.firstName = first;
this.lastName = last;
}
public string firstName { set; get; }
public string lastName { set; get; }
}
...
List<Persons> lst = new List<Persons>();
lst.Add(new Persons("firstname", "lastname"));
lst.Add(new Persons("firstname2", "lastname2"));
for (int i = 0; i < lst.Count; i++)
{
Console.Write("{0}: {2}, {1}", i, lst[i].firstName, lst[i].lastName);
if (i == 1)
{
lst[i].firstName = "firstname3";
lst[i].lastName = "lastname3";
Console.Write(" --> {1}, {0}", lst[i].firstName, lst[i].lastName);
}
Console.WriteLine();
}
}
Output:
0: lastname, firstname
1: lastname2, firstname2 --> lastname3, firstname3
Related
I am sorry I don't know if C# has this syntax or not and I don't know the syntax name. My code below, I want to add 2 people has the same name but not age. So I am wondering if C# has a brief syntax that I can change the Age property value when calling AddPerson method. Please tell me if I can do that? If can, how can I do? Thank you.
class Program
{
static void Main(string[] args)
{
//I want to do this
Person p = new Person
{
Name = "Name1",
//And other propeties
};
AddPerson(p{ Age = 20});
AddPerson(p{ Age = 25}); //Just change Age; same Name and others properties
//Not like this(I am doing)
p.Age = 20;
AddPerson(p);
p.Age = 25;
AddPerson(p);
//Or not like this
AddPerson(new Person() { Name = "Name1", Age = 20 });
AddPerson(new Person() { Name = "Name1", Age = 25 });
}
static void AddPerson(Person p)
{
//Add person
}
}
class Person
{
public string Name { get; set; }
public int Age { get; set; }
//And more
}
If Person is a Record-Type, then yes: by using C# 9.0's new with operator. Note that this requires C# 9.0, also note that Record-Types are immutable.
public record Person( String Name, Int32 Age );
public static void Main()
{
Person p = new Person( "Name1", 20 );
List<Person> people = new List<Person>();
people.Add( p with { Age = 25 } );
people.Add( p with { Age = 30 } );
people.Add( p with { Name = "Name2" } );
}
This is what I see in LinqPad when I run it:
I want to get the difference between two integers, in this case "Age" - subtract them.
Here my class and my list. I want to, with a method, take the age from Robin and Sara and show the age difference. Is this possible with LINQ or..?
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
public class LinqQuery
{
private readonly List<Person> _persons = new List<Person>
{
new Person {FirstName = "Robin", LastName = "Blixt", Age = 29},
new Person {FirstName = "Sara", LastName = "Johansson", Age = 44}
};
public IEnumerable<Person> GetAll()
{
return _persons;
}
public void difference()
{
?????
Console.ReadKey();
}
}
Thanks in advance.
You can use lambda expression to find specified index if FirstName is youre key and you have more items than two.
Please note that I did not check any erros (empty list etc.)
public void diff()
{
int indxRobin = lst.FindIndex((item) => { return item.FirstName == "Robin"});
int indxSara = lst.FindIndex((item) => { return item.FirstName == "Sara"});
return lst[indxRobin].Age - lst[indxSara].Age;
}
Using a cross-join you could calculate the age difference for all permutations in the list.
Of course, this is very crude and gives all duplicates, but it's easy from there to remove the duplicates in the query.
public void Difference()
{
var ageDifferences = from p1 in _persons
from p2 in _persons
select new
{
P1FullName = p1.FirstName + " " + p1.LastName,
P2FullName = p2.FirstName + " " + p2.LastName,
AgeDifference = Math.Abs(p1.Age - p2.Age)
};
foreach (var item in ageDifferences)
{
Console.Out.WriteLine("{0} and {1} have {2} years of age difference.", item.P1FullName, item.P2FullName, item.AgeDifference);
}
Console.ReadKey();
}
Thanks, #Tim Schmelter for the suggestion :)
public void difference()
{
int sara= _persons.FirstOrDefault(p=>p.FirstName=="Sara").Age;
int robin=_persons.FirstOrDefault(p=>p.FirstName=="Robin").Age;
int difference= Math.abs(sara-robin);
Console.ReadKey();
}
learning c# on my own , in a new project i have started working on,
one of the methods, accepts a List<string> type data, passed in as a parameter
. i would like to know , now ...that the need is for two of those lists, two types of data, or two groups,
and just for this example , say i have a pros and cons, or.. girls and boys,
these are actually 2 separated lists of elements or objects, i need to pass in, as a parameter
, and i want it to be passed as-one data-Type, and then, inside the method i will take care of separation of data lists , so.. instead of a couple of List objects i, thought(for a second there , that a Dictionary will be suitable...)
though i will only have one element (one item... each is a List) ,in this data type that i need to pass
what can i do to get this result ?
i will try to illustrate it :
List<string> classGirls = new List<string>();
List<string> classBoys = new List<string>();
for eace item in source... load both from the source
done List girls + List Boys are populated how would you pass them as one as a Dictionary Could though knowing you will only have One Girls And One Boys ListObjects ?
public bool foundAMatch( string Lookup, List<string> G , List<string> B){
{
var firstGirl = G.ElementAt(0);
var firstBoy = B.ElementAt(0);
return firstGirl == Lookup && firstBoy !=Lookup ;
}
instead i need it to be something Like
public bool foundAmatch(string Lookup, someDataType.... Kids)
{
var firstGirl = kids-girls <-- first entity in kids;
var firstBoy = kids-boys <-- first entity in Kids;
return firstGirl == Lookup && firstBoy !=Lookup ;
}
few things in mind ...as to properties of data , it should have good performance... naturally desired, though most importantly, it should be appropriate /easy to arrange and suitable for iterations using loops for sorting and as subject to all kind of statistic operations .
question is,
how will you implement the logic , is it an existing data Type... that i am thinking of ?
if it's not, what approach will you implement in this scenario choosing / crafting a data Type ?
You can solve this easily by using inheritance:
public abstract class Person
{
public string Name { get; private set; } // The setter is private because we only have to set this name when we create an instance
protected Person(string name)
{
Name = name;
}
}
public class Male : Person
{
public Male(string name) : base(name) // This constructor calls the constructor of the class it inherits and passes on the same argument
}
public class Female : Person
{
public Female(string name) : base(name)
}
public bool IsMatch(string needle, IEnumerable<Person> haystack)
{
var firstGirl = haystack.OfType<Female>().FirstOrDefault();
var firstBuy = haystack.OfType<Male>().FirstOrDefault();
return firstGirl != null &&
firstGirl.Name == needle &&
firstBoy != null &&
firstBoy.Name != needle;
}
edit:
I quite like extension methods, so I'd write the method like this:
public static class PersonExtensions
{
public static bool IsMatch(this IEnumerable<Person> haystack, string needle)
{
// same method logic in here
}
}
which you can then use like:
var people = new List<Person>();
people.Add(new Male { Name = "Bob" });
people.Add(new Female { Name = "Mary" });
var isMatch = people.IsMatch("Jane");
edit2:
It's probably even better to just have gender as a property of the Person class:
public enum Sex
{
Male,
Female
}
public class Person
{
public string Name { get; private set; }
public Sex Gender { get; private set; }
public Person(string name, Sex gender)
{
Name = name;
Gender = gender;
}
}
and change the method to:
var firstGirl = haystack.FirstOrDefault(p => p.Gender == Gender.Female);
var firstBoy = haystack.FirstOrDefault(p => p.Gender == Gender.Male);
The best way to get one collection is to create a class representing a boy as well as a girl. Please find the example below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private class Kid
{
public bool Gender { get; set; }
public String Name { get; set; }
}
private List<Kid> kids;
private void Form1_Load(object sender, EventArgs e)
{
// === Load data =================================================
kids = new List<Kid>();
kids.Add(new Kid { Name = "John", Gender = true });
kids.Add(new Kid { Name = "Paul", Gender = true });
kids.Add(new Kid { Name = "Jack", Gender = true });
kids.Add(new Kid { Name = "Brenda", Gender = false });
kids.Add(new Kid { Name = "Judith", Gender = false });
kids.Add(new Kid { Name = "Sofia", Gender = false });
Kid foundKid = foundAMatch("sofIa");
}
private Kid foundAMatch(string name)
{
var result = (from K in kids
where K.Name.ToLower() == name.ToLower()
select K);
if (result.Count() != 0)
return result.First();
else
return null;
}
private Kid foundAMatch(string name, bool gender)
{
var result = (from K in kids
where K.Name.ToLower() == name.ToLower() && K.Gender == gender
select K);
if (result.Count() != 0)
return result.First();
else
return null;
}
}
}
Does somebody know how to convert an arraylist to a list of dictionaries?
What do I have? I have an ArrayList (list) with a lot of strings:
foreach (string s in list)
{
Console.WriteLine(s);
}
output:
klaus
male
spain
lissy
female
england
peter
male
usa
...
As we see there is an order. The first entry is a NAME, second GENDER, third COUNTRY and then again NAME, GENDER... and so on.
Now for clarity I would like to store these attributes in a List of Dictionaries. Every List entry should be 1 Dictionary with these 3 Attributes. Is this a good idea? Whats the easiest way? I just search something to store this list in a better looking collection that is later easiert to handle. I have this:
List<Dictionary<string, string>> dlist = new List<Dictionary<string, string>>();
const int separate = 3;
foreach (string s in list)
{
//add list entries to dlist?
}
No it's not a good idea. Define a class.
At least something like this:
class Person
{
public string Name { get; set; }
public string Gender { get; set; }
public string Country { get; set; }
}
Even better would be to use an enum for Gender, and possibly a class (built-in or custom) for the country.
Anyway, to populate a collection with the above class, you'd use something like:
List<Person> result = new List<Person>();
for (int i = 0; i < list.Count; i += 3) {
result.Add(
new Person { Name = list[i], Gender = list[i+1], Country = list[i+2] });
}
Note that this loop lacks error checking on the count of items in the list, which should be a multiple of three.
enum Gender
{
Male = 0,
Female = 1
}
class Person
{
public string Name { get; set; }
public Gender Gender { get; set; }
public string Country { get; set; }
public Person(string name, Gender gender, string country)
{
this.Name = name;
this.Gender = gender;
this.Country = country;
}
}
Usage:
List<Person> persons = new List<Person>();
Person person;
for (int i = 0; i < list.Count; i += 3) {
{
person = new Person(list[i], (Gender)Enum.Parse(typeof(Gender), list[i+1], true), list[i+2]);
persons.add(person);
}
I would recommend using a class to encapsulate your entry:
class Entry
{
public String Name { get; set; }
public String Gender { get; set; }
public String Country { get; set; }
}
Then add to a list of Entrys
List<Entry> elist = new List<Entry>();
for (int i = 0; i < list.Count; i += 3)
{
var ent = new Entry() { Name = list[i],
Gender = list[i+1],
Country = list[i+2]};
elist.Add(ent);
}
Or you could use Tuples:
List<Tuple<string, string, string>> tlist =
new List<Tuple<string, string, string>>();
for (int i = 0; i < list.Count; i += 3)
{
Tuple<string,string, string> ent
= new Tuple<string,string,string>(list[i], list[i+1], list[i+2]);
tlist.Add(ent);
}
the simplest way to implement that - it's create a new class for representing someone in you list with 3 props:
public class Someone {
public string Name { get; set; }
public string Gender { get; set; }
public string Country { get; set; }
}
And than you can fill your destination list with Someone entries:
List<Someone> dList = new List<Someone>();
for(int i = 0; i < list.Count; i += 3)
dList.Add(new Someone() { Name = list[i], Gender = list[i+1], Country = list[i+2] });
p.s. this code may contain errors because I don't have access to computer with VS installed.
You may have a class to hold the data like:
public class Info
{
public string Name { get; set; }
public string Gender { get; set; }
public string Country { get; set; }
}
then you can have a dictionary like this
Dictionary<int, Info> infoDict = new Dictionary<int, Info>();
then you can start reading and prepare the dictionary.
var listSrc = new List<string>
{
"klaus",
"male",
"spain",
"lissy",
"england",
"female",
"peter",
"usa",
"male",
};
var dlist = new List<Dictionary<string, string>>();
for (var i = 0; i < listSrc.Count; i++)
{
var captions = new List<string>
{
"Name",
"Gender",
"Country"
};
var list = listSrc.Take(3).ToList();
listSrc.RemoveRange(0, 3);
dlist.Add(list.ToDictionary(x => captions[list.IndexOf(x)], x => x));
}
Its simple. You are working for a class that contains three data variables named :
String name;
String gender;
String country;
So make a class that contains all three of these variables. As for eg:
class Dictnary
{
public Dictnary(String nameFromCall, String genderFromCall, String countryFromCall)
{
this.name = nameFromCall;
this.gender = genderFromCall;
this.country = countryFromCall;
}
}
To answer the question in the title, this is probably the most succinct way to do the conversion:
for (int i = 0; i < list.Count; i += 3) {
dlist.Add(new Dictionary<string, string>() {
{ "name", (string)list[i] },
{ "gender", (string)list[i+1] },
{ "country", (string)list[i+2] }
});
}
(If you switch from an ArrayList to a List<string>, you can drop the (string) cast.)
That said, unless you really need a dictionary for some technical reason, your problem is better solved using one of the class-based approaches suggested in the other answers.
All the examples I see of using the IndexOf() method in List<T> are of basic string types. What I want to know is how to return the index of a list type that is an object, based on one of the object variables.
List<Employee> employeeList = new List<Employee>();
employeeList.Add(new Employee("First","Last",45.00));
I want to find the index where employeeList.LastName == "Something"
int index = employeeList.FindIndex(employee => employee.LastName.Equals(somename, StringComparison.Ordinal));
Edit: Without lambdas for C# 2.0 (the original doesn't use LINQ or any .NET 3+ features, just the lambda syntax in C# 3.0):
int index = employeeList.FindIndex(
delegate(Employee employee)
{
return employee.LastName.Equals(somename, StringComparison.Ordinal);
});
public int FindIndex(Predicate<T> match);
Using lambdas:
employeeList.FindIndex(r => r.LastName.Equals("Something"));
Note:
// Returns:
// The zero-based index of the first occurrence of an element
// that matches the conditions defined by match, if found;
// otherwise, –1.
you can do this through override Equals method
class Employee
{
string _name;
string _last;
double _val;
public Employee(string name, string last, double val)
{
_name = name;
_last = last;
_val = val;
}
public override bool Equals(object obj)
{
Employee e = obj as Employee;
return e._name == _name;
}
}
Sorry, one more for good measure :)
int index = employees.FindIndex(
delegate(Employee employee)
{
return employee.LastName == "Something";
});
Edit: - Full Example in .NET 2.0 Project.
class Program
{
class Employee { public string LastName { get; set; } }
static void Main(string[] args)
{
List<Employee> employeeList = new List<Employee>();
employeeList.Add(new Employee(){LastName="Something"});
employeeList.Add(new Employee(){LastName="Something Else"});
int index = employeeList.FindIndex(delegate(Employee employee)
{ return employee.LastName.Equals("Something"); });
Console.WriteLine("Index:{0}", index);
Console.ReadKey();
}
}
I prefer like this
private List<Person> persons = List<Person>();
public PersonService()
{
persons = new List<Person>() {
new Person { Id = 1, DOB = DateTime.Today, FirstName = "Pawan", LastName = "Shakya" },
new Person { Id = 2, DOB = DateTime.Today, FirstName = "Bibek", LastName = "Pandey" },
new Person { Id = 3, DOB = DateTime.Today, FirstName = "Shrestha", LastName = "Prami" },
new Person { Id = 4, DOB = DateTime.Today, FirstName = "Monika", LastName = "Pandey" },
};
}
public PersonRepository.Interface.Person GetPerson(string lastName)
{
return persons[persons.FindIndex(p=>p.LastName.Equals(lastName, StringComparison.OrdinalIgnoreCase))];
}
The answer is for those coming here to know why IndexOf()
doesn't work.
Your class must override Equals method of object possessing the following declaration.
public override bool Equals(object obj)