I have two lists
List<Country> list1;
List<string> list2;
public class Country
{
string Id { get; set; }
string Name { get; set; }
}
I wish to copy member "Name" to list2, how do I do that?
public class Country {
public string Id {get; set;}
public string Name {get; set;}
}
// In using method ...
{
List<Country> list1 = // assign countries
// Either
List<string> list2 = new List<string>();
list1.Select(c => c.name).ForEach(list2.Add);
// OR
var list2 = list1.Select(c => c.name).ToList();
}
Here is a tutorial about LINQ
Answer to comment about "c":
Linq makes heavy use of "Lambda-Expressions" and the "c" stands for every member of
the List (and more generically of the Enumeration). On the right side of the function operator you can have
either an Expression, an anonymous method or a delegate. The variable
name is free to choose, it could have been "country", "x" or whatever
you want. I just usually take the first letter of the class-name.
There is one more way that wasn't mentioned.
You can use the List<T> class constructor which accepts an IEnumerable<T>:
var names = new List<string>(list1.Select(x => x.Name));
Well, first of all you should change your class and make Name field as public:
public class Country
{
public string id { get; private set; }
public string name { get; private set; }
}
To create list of names you should use LINQ and select clause:
list2 = list1.Select(x => x.name).ToList();
Related
I need the possiblity to create Code in C# like this
public class SummaryA
{
public string name { get; set; }
public string surename { get: set; }
public int age { get; set;}
}
now I create an list object from the class SummaryA
List<SummaryA> list1= new List<SummaryA>();
yet I need the possibility to remove the column age from the list Summary, anyone have ideas?
I need this for some more columns, so I wish the list was dynamically or some things else.
sry for my bad english.
To completely remove the column you really need another class to store the data in, for example:
public class AgelessSummaryA
{
public string name { get; set; }
public string surename { get: set; }
}
And now you can project the first list into a new list of this class with Linq and Select:
List<AgelessSummaryA> agelessSummaries = ageSummaries
.Select(s => new AgelessSummaryA
{
name = s.name,
surename = s.surename
})
.ToList();
To use it for in a grid or for some display i guess, then you can use anonymous types where you can shape the data the way you like:
var projectedList = (from l in list1
select new
{
name = l.name,
surename = l.surename
}).ToList();
I have a list of foo called crepes. I want to return foo where bar.doritos == "coolRanch"
class foo
{
List<bar> item;
string candy;
string beer;
}
class bar
{
string doritos;
string usb;
}
var item = crepes.item.Where(x => x.doritos == "coolRanch").FirstOrDefault();
From other threads, i've pieced together the above linq query, but crepes.item throws an error. "List does not contain a definition for 'item' and no definition for 'item' accepting first argument...
Given that crepes is a List<Foo>, you need to add an additional level to the linq query.
var item = crepes.Where(a => a.item.Any(x => x.doritos == "coolRanch")).FirstOrDefault();
Your item access modifier is private (this is C# default for class), it should be made public
This goes for your doritos too
Also, since your crepes is a List, put additional layer of LINQ (as also suggested by others) to completely fix it, something like this
var item = crepes.Where(f => f.item.Any(b => b.doritos == "coolRanch")).FirstOrDefault(); //f is of foo type, b is of bar type
If you fix your classes like this
class Foo
{
public List<Bar> Items { get; set; }
public string Candy { get; set; }
public string Beer { get; set; }
}
class Bar
{
public string Doritos { get; set; }
public string Usb { get; set; }
}
Your query will look like
var crepes = new List<Foo>();
var item = crepes.FirstOrDefault(f => f.Items.Any(b => b.Doritos == "coolRanch"));
Here, we are trying to get the first Foo which has at least one Bar in Items where Doritos == "coolRanch".
I have a problem:
In my code I have this obj
//:extension for being saved locally
public class FOO
{
public int ID { get; set; }
public string STRINGVALUE{ get; set; }
public int INTVALUE { get; set; }
//ecc..
//SelectAll() method which returns all FOO in local DB
}
Now what I want is, in some cases, to pick all FOO obj where STRINGVALUE (or INTVALUE) is not duplicated.
For example:
List<FOO> fooes = new FOO().SelectAll();
List<FOO> uniqueIntFoo = fooes.distinct(); //here i have to set the clause
There is the Distinct() method in Linq, but it compare the entire item, not a single variable of it.
Any of you know how can I do it?
What about grouping the results, something like:
By both Int and StrValue:
var uniqueItems = fooes.GroupBy(x => new{x.IntVal, x.StrVal});
By IntVal:
var uniqueItems = fooes.GroupBy(x => x.IntVal);
Edit, as suggested by question's author:
fooes.GroupBy(x => x.INTVALUE).Select(y => y.First()).Distinct().ToList();
I'm trying to follow the instruction from this page (http://www.asp.net/mvc/tutorials/mvc-5/introduction/adding-search) on how to create a search page with a dropdown list for a site. But can't seem to get the dropdown list. It keeps giving me this error:
System.ArgumentException: DbSortClause expressions must have a type that is order comparable. Parameter name: key
The problem is: CountryList.AddRange(CountryQry.Distinct());
SEARCH CONTROLLER :::
public ActionResult Index(string location, string searchString)
{
var CountryList = new List<Country>();
var CountryQry = from d in db.Stuffs
orderby d.Country
select d.Country;
CountryList.AddRange(CountryQry.Distinct());
ViewBag.location = new SelectList(CountryList);
var stuff = from m in db.Stuffs
select m;
if (!String.IsNullOrEmpty(searchString))
{
stuff = stuff.Where(s => s.stuffName.Contains(searchString));
}
if (!String.IsNullOrEmpty(location))
{
stuff = stuff.Where(x => x.Country.countryName == location);
}
return View(stuff);
}
VIEW :::
<form>
#using (Html.BeginForm("Index","Search",FormMethod.Get)){
#Html.TextBox("SearchString", new { placeholder = "text" })
#Html.DropDownList("location", "All")
}
</form>
Model ::: (this was auto-generated from the database)
public partial class Stuff
{
public string stuffId { get; set; }
public string stuffName { get; set; }
public string countryId { get; set; }
public virtual Country Country { get; set; }
}
My c# knowledge is very limited, thus, I'm hoping someone can help me with this.
Any help is appreciated! Thank you!
The error tells you that the Distinct method expects a criterion for comparing Country objects. Your Country class is a complex class, which probably has several properties and does not implement the IComparer interface. This interface declares a method for comparing two objects and it is used by the Distinct method to find out if two objects are "equal".
You should implement the IComparer/IComparable interfaces in the Country class.
Assuming your Country class has a similar structure (regarding properties) you can do something like this (two countries are compared based on their name, but you can easily change the comparison property):
public class Country : IComparer
{
public string Name { get; set; }
public string Capital { get; set; }
public int Population { get; set; }
int IComparer.Compare(object a, object b)
{
Country c1=(Country )a;
Country c2=(Country )b;
if (c1.Name < c2.Name )
return 1;
if (c1.Name > c2.Name )
return -1;
else
return 0;
}
}
EDIT: The IEqualityComparer interface might be required instead of IComparer.
Another EDIT: One way around all this is to use:
var uniqueCountries = CountryQry.GroupBy(c => c.Name).Select(g => g.FirstOrDefault());
I have a List<StreetSuffix> that I would like to order alphabetically while maintaining the most used at the top.
My class Looks like this:
public class StreetSuffix
{
public StreetSuffix(string suffix, string abbreviation, string abbreviation2 = null)
{
this.Suffix = suffix;
this.Abbreviation = abbreviation;
this.Abbreviation2 = abbreviation2;
}
public string Suffix { get; set; }
public string Abbreviation { get; set; }
public string Abbreviation2 { get; set; }
}
I know I can order my list using:
Suffix.OrderBy(x => x.Suffix)
This list will be used to fed a combobox, from the items on the list I would like to keep at the top the following suffix on the same order:
Road
Street
Way
Avenue
Is there a way to do this using LINQ or do I have to intervent myself for this specific entries ?
You could do this:
// Note: reverse order
var fixedOrder = new[] { "Avenue", "Way", "Street", "Road" };
Suffix.OrderByDescending(x => Array.IndexOf(fixedOrder, x.Suffix))
.ThenBy(x => x.Suffix);
Use OrderBy..(priority order) ThenBy..(secondary order)
Or, implement a custom IComparer and use that with OrderBy. The primary ordering will be the outside conditional.