I have the following list:
List<string> department = new List<string>();
Add the data one by one is working but I cannot push the multiple data into the list:
using System;
namespace Linq_Basics
{
class Program
{
static void Main(string[] args)
{
List<names> names = new List<names>();
names.Add(new names { Firstname = "viki", Lastname = "Amar" });
names.Add(new names { Firstname = "Sankar", Lastname = "Pandi" });
names.Add(new names { Firstname = "Bala", Lastname = "Murugan" });
foreach (var v in names)
{
Console.WriteLine("The Firstname is {0} and the last name is {1}", v.Firstname, v.Lastname);
}
List<string> department = new List<string>();
department.Add(new List<string> { "ece", "cse" });
Console.ReadKey();
}
}
class names
{
public string Firstname { get; set; }
public string Lastname { get; set; }
}
}
Use List<T>.AddRange method to add sequence of strings to list of strings:
department.AddRange(new List<string> { "ece", "cse" });
Or simply call Add twice to avoid new list creation:
department.Add("ece");
department.Add("cse");
Or use collection initializer if you want to hold only these two strings in department list:
var department = new List<string> { "ece", "sce" };
List<string> department = new List<string> { "ece", "cse" };
department defines a list which holds the string type. You are trying to add a List<string> to it instead of a string:
List<string> department = new List<string>();
department.Add(new List<string> { "ece", "cse" });
Needs to be:
department.Add("ece")
//etc...
Or:
department = new List<string>() { "ece", "cse" };
Or:
department.AddRange(new List<string> { "ece", "cse" });
Related
How to convert List<string> to List<object> property in c#
We have a list of email id's
List<string> str= new List<string>{"abc1#gmail.com","abc2#gmail.com"};
and now we have to assign these email IDs to the list of an employee List<Employee> emailId property.
var emplist = new List<Employee>() ;
You can use Select().
var emplist = str.Select(x => new Employee { EmailId = x }).ToList();
Select() is used for projecting each element of a sequence(in your case it is string email id) into a new sequence i.e. the Employee object.
We can convert or assign List<string> to List<object> to specific property
//here Employee is an Object type
public static void Main(string[] args)
{
List<string> list = new List<string>() { "abc1#gmail.com", "abc2#gmail.com" } ;
var emplist= new List<Employee>() ;
if(list.Any())
list.ForEach(str => emplist.Add(new Employee { EmailId = str }));
Console.ReadLine();
}
public class Employee {
public string EmailId { get; set; }
public string Address { get; set; }
}
I am new to C# and I have been struggling to do the following:
I'm trying to List a list in a console application, I have a model called "TeamModel"
public class TeamModel
{
public int Id { get; set; }
public string TeamName { get; set; }
public List<PersonModel> TeamMembers { get; set; } = new List<PersonModel>();
public TeamModel()
{
}
}
In my main class I have the following:
class Program
{
static void Main(string[] args)
{
List<TeamModel> TeamOne = new List<TeamModel>(){new TeamModel() { Id =1, TeamName = "x's Team", TeamMembers = null}};
List<TeamModel> TeamTwo = new List<TeamModel>(){new TeamModel() { Id =2, TeamName = "y's Team", TeamMembers = null}};
List<TeamModel> TeamThree = new List<TeamModel>(){new TeamModel() { Id =3, TeamName = "z's Team", TeamMembers = null}};
List<List<TeamModel>> listOfTeams = new List<List<TeamModel>> (){TeamOne,TeamTwo,TeamThree};
foreach (List<TeamModel> list in listOfTeams)
{
Console.WriteLine(list);
}
}
}
Now when I run the program I expect the result to be:
1,x's Team ,
2,y's Team ,
3,z's Team
Instead what I'm getting is
System.Collections.Generic.List`1[TeamModel]
System.Collections.Generic.List`1[TeamModel]
System.Collections.Generic.List`1[TeamModel]
If I change the foreach to :
foreach (List<TeamModel> list in listOfTeams)
{
Console.WriteLine(String.Join(", ", list));
}
I get this:
TeamModel
TeamModel
TeamModel
You can achieve this by using
foreach (List<TeamModel> list in listOfTeams)
{
foreach (var team in list)
{
Console.WriteLine(team.Id + " " + team.Name);
}
}
Is there a reason that TeamOne, TeamTwo and TeamThree are created as lists given that each "list" contains a single team? The following implementation would achieve what you stated was the expected output:
static void Main(string[] args)
{
TeamModel TeamOne = new TeamModel { Id = 1, TeamName = "x's Team", TeamMembers = null };
TeamModel TeamTwo = new TeamModel { Id = 2, TeamName = "y's Team", TeamMembers = null };
TeamModel TeamThree = new TeamModel { Id = 3, TeamName = "z's Team", TeamMembers = null };
List<TeamModel> listOfTeams = new List<TeamModel> { TeamOne, TeamTwo, TeamThree };
foreach (TeamModel team in listOfTeams)
{
Console.WriteLine($"{team.Id}. {team.TeamName}");
}
}
If you genuinely need a list of lists then the following implementation will work. The only difference from your own solution is an additional foreach inside the one you had:
static void Main(string[] args)
{
List<TeamModel> TeamOne = new List<TeamModel>() { new TeamModel() { Id = 1, TeamName = "x's Team", TeamMembers = null } };
List<TeamModel> TeamTwo = new List<TeamModel>() { new TeamModel() { Id = 2, TeamName = "y's Team", TeamMembers = null } };
List<TeamModel> TeamThree = new List<TeamModel>() { new TeamModel() { Id = 3, TeamName = "z's Team", TeamMembers = null } };
List<List<TeamModel>> listOfTeams = new List<List<TeamModel>>() { TeamOne, TeamTwo, TeamThree };
foreach (List<TeamModel> list in listOfTeams)
{
foreach (TeamModel team in list)
{
Console.WriteLine($"{team.Id}. {team.TeamName}");
}
}
}
Using Linq
You can Flatten the nested list using .SelectMany() and then either you can iterate over flatten list or you can convert it into List of string and then print it.
Projects each element of a sequence to an IEnumerable and flattens
the resulting sequences into one sequence.
var strTeamDetails = listOfTeams
.SelectMany(teams => teams) //Flatten the List.
.Select(individualTeam => $"{individualTeam.Id} {individualTeam.Name}"); //Convert to IEnumearable of string
Console.WriteLine(string.Join(",\n", strTeamDetails)); //Print
You may want to consider overriding the ToString() method for your TeamModel class;
From the link above;
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return "Person: " + Name + " " + Age;
}
}
You can test the ToString method as shown in the following code example:
Person person = new Person { Name = "John", Age = 12 };
Console.WriteLine(person);
// Output:
// Person: John 12
I have a list of objects (List1) and list of string (List2 - list of Names of the objects)
I need to get all objects from List1 if the object.Name does not exists in List2
How can write this LINQ C#.?
public class Class1
{
public string Name {get;set;}
}
var List1 = new List<Class1>();
var List2 = new List<string>();
var result = List1.Where(x=>!List2.Contains(x.Name)).ToList();
Or:
var result = List1.Where(x=>!List2.Any(n=>n==x.Name)).ToList();
class Program
{
static void Main(string[] args)
{
List<List1Class> listClass = new List<List1Class>();
listClass.Add(new List1Class { ObjectName = "obj1" });
listClass.Add(new List1Class { ObjectName = "obj2" });
listClass.Add(new List1Class { ObjectName = "obj3" });
listClass.Add(new List1Class { ObjectName = "obj4" });
List<string> listString = new List<string>();
listString.Add("obj2");
listString.Add("obj4");
listString.Add("obj5");
var filterlist = listClass.Where(l => !listString.Contains(l.ObjectName)).ToList();
}
}
class List1Class
{
public string ObjectName { get; set; }
//Add other property
}
When creating objects like:
var customers = new Customers
{
Persons = new List<Person>
{
new Person { CustomId = "111" },
new Person { CustomId = "222" }
},
Organizations = new List<Organization>
{
new Organization { CustomId = "333" }
},
Keys = new HashSet<string> { "111", "222", "333" }
};
I want to change the initialization of Keys to use the previous value from Person[0].CustomId, Person[1].CustomId and Organization[0].CustomId. (Not hardcoded like this "111", "222", "333")
Is there a simple way to do this inside this type of initialization? I can add the keys after the initialization of customers like this:
foreach (var person in customers.Persons)
{
customers.Keys.Add(person.CustomId);
}
foreach (var org in customers.Organizations)
{
customers.Keys.Add(org.CustomId);
}
But I cannot create Keys from Person and Organization properties in the same initialization as customers?
No, you can't do that.
You can create the collections first, and concatenate the selected keys:
var persons = new List<Person>
{
new Person { CustomId = "111" },
new Person { CustomId = "222" }
};
var organizations = new List<Organization>
{
new Organization { CustomId = "333" }
};
var keys = persons.Select(p => p.CustomId)
.Concat(organizations.Select(o => o.CustomId));
var customers = new Customers
{
Persons = persons,
Organizations = organizations,
Keys = new HashSet<string>(keys),
}
But like others said, there's more issues with this implementation. Do you want to use this syntax for every consumer of the Customers class? How will you keep the key collection up to date with the Persons and Organizations collections, like when you add or remove items from them?
public class Customers
{
public List<Person> Persons { get; set; }
public List<Organization> Organizations { get; set; }
public Customers()
{
Persons = new List<Person>();
Organizations = new List<Organization>();
}
public Customers(IEnumerable<Person> persons,
IEnumerable<Organization> organizations)
: this()
{
Persons.AddRange(persons);
Organizations.AddRange(organizations);
}
public IEnumerable<string> Keys
{
return Persons.Select(p => p.CustomId)
.Concat(Organizations.Select(o => o.CustomId));
}
}
Then a call site may look like this:
var persons = new List<Person>
{
new Person { CustomId = "111" },
new Person { CustomId = "222" }
};
var organizations = new List<Organization>
{
new Organization { CustomId = "333" }
};
var customers = new Customers(persons, organizations);
var keys = customers.Keys;
Make Keys into a public property like:
public HashSet<string> Keys
{
get
{
// create and return a new hashset from persons and organizations
}
}
This way you newer have to think about updating your Keys member.
Say I have codes:
class Program
{
static void Main( string[] args )
{
Company companyA = new Company();
Company companyB = new Company();
companyA.Employees = new List<string> { "A1", "A2" };
companyB.Employees = new List<string> { "B1", "B2" };
List<Company> companyList = new List<Company> {companyA, companyB};
List<string> allEmployees = new List<string>();
foreach( Company company in companyList )
{
allEmployees.AddRange( company.Employees );
}
// ...
}
class Company
{
public List<string> Employees { get; set; }
}
}
I want to fill allEmployees with the employees from all companies in companyList.
Instead of using the above codes, is it possible to get the same result by using a single LINQ statement on companyList object? May be something like:
List<string> allEmployees = companyList.Select( ...? )
Use SelectMany
List<string> allEmployees = companyList.SelectMany(x => x.Employees).ToList();
You can use AddRange + SelectMany:
allEmployees.AddRange( companyList.SelectMany(c => c.Employees) );
If you don't want to add them to an already existing list but to create a new one:
List<string> allEmployees = companyList.SelectMany(c => c.Employees).ToList();