This question already has answers here:
Cast IList to List
(9 answers)
Closed 9 years ago.
I have a function that takes IList<string> someVariable as a parameter. I want to convert this to a list so I can sort the values alphabetically.
How do I achieve this?
you can just do
var list = new List<string>(myIList);
list.Sort();
or
var list = myIList as List<string>;
if (list != null) list.Sort; // ...
IList<string> someVariable = GetIList();
List<string> list = someVariable.OrderBy(x => x).ToList();
IList implements IEnumerable. Use the .ToList() method.
var newList = myIList.ToList();
newList.Sort();
You can use linq to sort an IList<string> like so:
IList<string> foo = .... ; // something
var result = foo.OrderBy(x => x);
You don't have to convert to a List to sort things. Does your sorting method require a List but not accept an IList. I would think this is the actual problem.
Furthermore if you really need a List, if your IList realy is a List (which is somewhat likely) you can just interpret it as such. So I would first check if it is already a List before creating a new one
var concreteList = parameter as List<T> ?? parameter.ToList();
Related
This question already has an answer here:
How to dynamically iterate/detect member types in ValueTuple that has null members? [duplicate]
(1 answer)
Closed 2 years ago.
Let's say I have a tuple that looks like this:
(string, string, string) myTuple = ("Poop","Stack","Overflow");
Is there an elegant way to convert this to a list of strings that would look like this?
var myList = new List<string>() { myTuple.Item1, myTuple.Item2, myTuple.Item3 };
I can't ForEach over a tuple, or convert it into an enumerable it seems...
Thank you!
Assuming that you want to handle value tuples which have fields of the same type, for starters you can use simple reflection:
var myList = myTuple.GetType()
.GetFields()
.Select(fi => fi.GetValue(myTuple))
.Cast<string>()
.ToList();
Which will have some performance penalties.
If you have tuples of the same size you can just introduce the method:
public static List<T> GetFromTuple<T>(ValueTuple<T,T,T> tuple)
{
return new List<T> {tuple.Item1, tuple.Item2, tuple.Item3};
}
Also using reflection you can write a small piece of code which will generate methods for all ValueTuple's of different types (or create T4 template for it).
This question already has answers here:
c# list.OrderBy not working at all? [duplicate]
(4 answers)
Closed 3 years ago.
I must order a list according to a string contained in each element of the list.
I have a ribbonDropDown element which contains a list of ribbonDropDownItem. Each of those item contains a string from which I want to reorder the item position in the ribbonDropDown alphabatically.
I think my problem can be solve just by considering I have a List of object which contain a string field.
I tried this :
List<myObject> myList = aList;
myList.OrderBy(i => i.Name, StringComparer.Ordinal);
and also
myList.OrderBy(i => i.Name);
I expect the result to be order from a->z or z->a depending on the method I use (OrderBy or OrderBy descening).
For now my result is the same order of my list before the operation.
Is it possible to use this method for that or should I use something else ?
I'd like not to use a for loop.
You need to reassign the return of the .OrderBy() to the original list.
myList = myList.OrderBy(i => i.Name).ToList();
.OrderBy() does not change the existing list, it returns the input list with the modifications as a new IEnumerable<>.
This question already has answers here:
Update all objects in a collection using LINQ
(18 answers)
Closed 7 years ago.
I am trying to add a SELECT ALL functionality to my grid with LINQ, but I get a compilation error.
List<Person_> PeopleUpdated = People.ToList().ForEach(a => a.SELECTED = true).ToList();
It says
Cannot implicitly convert type 'void' to
'System.Collections.Generic.List <
LogoSapHrIntegration.frmXmlUpload.Person_>'
what am I doing wrong?
The List<T>.ForEach has no return value (ie void), so you can't run ToList() against that. (see MSDN)
ForEach a specific action for each item in the list (just like doing a real for loop).
In your case a simple for loop to select all is most efficient.
foreach (var person in People)
person.Selected = true
List<T>.ForEach returns void (in your case, it changes your collection in place). ForEach takes an Action<T> and executes that on each item of your list.
See List(T).ForEach on MSDN
The ForEeach method (which is not LINQ) runs an action on each item in the list, it's not used to filter out items from a list so it doesn't return a result.
Just run the method on each item; there is no result to assign:
People.ToList().ForEach(a => a.SELECTED = true);
If you wanted a new list of items where the property was changed, you would need to clone the items to make them separate from the originals:
List<Person_> PeopleUpdated = People.ToList().Select(a => {
Person_ b = a.Clone();
b.SELECTED = true;
return b;
}).ToList();
(If the class doesn't support cloning, you would need to implement the Clone method (and preferably the IClonable interface).)
First of all, you can use a normal foreach loop:
foreach (var person in people)
{
person.Selected = true;
}
Which is the simplest and cleanest.
If you really want to jump to hoops and use LINQ, you can use ConvertAll:
var list = new List<Person> { new Person(), new Person() };
var convertedPeople = list.ConvertAll(person =>
{
person.Selected = true;
return person;
});
This question already has an answer here:
Check for any element that exists in two collections
(1 answer)
Closed 9 years ago.
Is there a way to determine if a collection contains at least one element from another collection?
You can use the Any().
var listA = new List<int>();
var listB = new List<int>();
bool hasCommonItem = listA.Any(i => listB.Contains(i));
Moreover, you can write an IEqualityComparer implementation to pass it as a parameter to the Contains() if necessary.
Sure there is.
var sourceCollection = GetSourceCollection();
var otherCollection = GetAnotherCollection();
var hasAtLeastOne = sourceCollection.Intersect(sourceCollection).Any();
I assumed your collections are of the same type: IEnumerable<T> with the same T generic parameter.
It's gonna load whole sourceCollection first, and then fetch one element at a time from otherCollection until first common one is found.
col1.Any(x => col2.Any(y => x==y));
Here's what I'm trying to do:
ObjectA
{
int ID;
string name;
}
I want to convert Dictionary to List where the strings in the list are the .name values of the ObjectAs in the dictionary. Obviously I could manually iterate over the dictionary values and build the list that way, but I was hoping there'd be a simpler or faster way in C# / .NET. A LINQ solution is fine, if it's simpler and faster than/as fast as:
List<string> aNames = new List<string>();
foreach(ObjectA a in DictionaryA.Values)
aNames.Add(a.name);
Here's the non-query-expression form of Matthew's answer:
var names = DictionaryA.Values.Select(x => x.name).ToList();
(I tend not to use query expressions when I'm just doing a single select or a single where, especially if I also need to call another method such as ToList.)
Alternatively:
var names = DictionaryA.Select(x => x.Value.name).ToList();
(from val in DictionaryA.Values select val.name).ToList()
There's plenty of ways to do this once you have a query:
IQueryable<string> query = DictionaryA.Values.Select(v => v.name);
//use the Constructor of List<T> that accepts IEnumerable<T>
List<string> aNames = new List<string>(query);
//
//or use the AddRange method for existing Lists
List<string> aNames = new List<string<();
aNames.AddRange(query);
//
//or use the Enumerable.ToList extension method
List<string> aNames = query.ToList();