In operator using linq query - c#

I have a list of items (InputList). Along with this I have a list of names (Names). Now I need only those items from InputList whose names are present in the Names list.
One solution is that I do a loop on Names list and check if it is present in InputList or not.
foreach (var name in names)
{
var result = InputList.FirstOrDefault(i => i.Name == name);
if (result != null)
outputList.Add(result);
}
There is IN operator in SQL in which we provide list and query returns desired result. Can I achieve the same using Linq?

That you want is the following:
var result = inputList.Where(x=>Names.Contains(x.Name));
the above query selects all the elements of inputList, whose name is contained in the Names list.
The signature of Contains method is bool Contains(T item), where T is the type of objects that are contained in your list. If the item you pass to this method is contained in your list returns true. Otherwise, it returns false.
For further documentation on the Contains method, please have a look here.

Related

Using List in FindAll function -C# LinQ

I am having the below line of code to filter a list
items = ctx.listName.ToList().FindAll(x=>x.LocationId= locationId); //int locationId passed as parameter
Now, instead of having just one location (locationId), is there a way to have multiple locations and use them in the query?
Like instead of int locationId can we use List<int> locations and have something like this
items = ctx.listName.ToList().FindAll(x=>x.LocationId in locations)
You can use LINQ Contains() extension method like this.
The Linq Contains Method in C# is used to check whether a sequence or collection (i.e. data source) contains a specified element or not. If the data source contains the specified element, then it returns true else return false
List<int> locations= // code to get location id's here
items = ctx.listName.Where(x=>locations.Contains(x.locationId)).ToList();

Comparing two lists and removing each item that contains an entry from the other list

I'm trying to essentially copy any list items in fileManifest but only those that don't contain in any of the items from exclusionFilters to a newly initialized list. I haven't figured out an elegant way to do this other than a nested foreach loop.
Does someone by chance have a better solution for this problem? Maybe LINQ?
var fileManifest = new List<string>()
{
#"C:\Test\Directory1\File1.xml",
#"C:\Test\Directory1\File2.xml",
#"C:\Test\Directory1\Directory2\File1.xml",
};
var exclusionFilters = new List<string>()
{
#"Directory2\"
};
var filteredList = new List<string>();
Expected Output of filteredList:
C:\Test\Directory1\File1.xml
C:\Test\Directory1\File2.xml
var filteredList = fileManifest.Where(x => exclusionFilters.All(y => !x.Contains(y))).ToList();
Description:
Enumerable.Where Method: Filters a sequence of values based on a predicate.
Enumerable.All Method: Determines whether all elements of a sequence satisfy a condition.
String.Contains(String) Method: Returns a value indicating whether a specified substring occurs within this string.
Enumerable.ToList Method: Creates a List from an IEnumerable.

Using LINQ .Select and .Any in single line

I am looking to optimize some code to less lines and without the need for "for loops" using LINQ if possible. I saw a similar post asking for Select and Where in a single line but it wasn't exactly the same.
Suppose I have:
A list of elements in "fields" which has properties "Id" and "Name" which can be retrieved calling respectively .Id and .Name
Ex.
fields[0] = Element
fields[0].Id = 12345
fields[0].Name = Name01
I want to create a new list "filteredIds" containing the Id properties of selected fields.
This is the for loop version:
List<Id> filteredIds = new List<Id>();
fields = {Element1, Element2, ...}; //List of Elements
List<string> selectedNames = new List<string>() {"Name01", "Name05", "Name10"};
foreach (Element e in fields):
if (selectedNames.Contains(e.Name())
{
filteredIds.Add(e.Id);
}
Can this be done in a single line like this in LINQ?
filteredIds = fields.Select(i => i.Id).Any(o => selectedNames.Contains(o.Name)).ToList();
Any() returns true/false values. You need to call Where() to actually filter results.
filteredIds = fields.Where(o => selectedNames.Contains(o.Name)).Select(i => i.Id).ToList();
Almost correct. You should use Where to filter the list, not Any.
Any returns a boolean which is true if at least one element in the list satisfies the predicate, while Where returns all the elements that satisfy the predicate.
You also need to apply the Where filter before the Select, as the name property is removed by the select.

How to check if a list contains item in dynamic list using linq

In a dynamic List<XElement> I want to get all the values that contains specific attValue.
To do that I'm using this:
return new DynamicXml(from item in _elements
where item.Attribute("attName").Value.Contains("attValue")
select item);
and To get attributes with more than one attribute value, I could use something like this:
return new DynamicXml(from item in _elements
where item.Attribute("attName").Value.Contains("attValue") ||
item.Attribute("attName").Value.Contains("attValue2")
select item);
all of the previous code works properly, now I'm trying to do the exact thing in the second code block, but instead of adding static conditions i need to pass a list that contains the attribute values, to get the values, but it returns wrong data.
I tried to do it like this:
This return all the value no matter what their attribute Values are.
return new DynamicXml(from item in _elements
where attValues.Any(v => v.Contains(item.Value))
select item);
This do not return anything:
return new DynamicXml(from item in _elements
where attValues.Contains(item.Value)
select item);
Note: attValues is List
Edit:
_elements contains properties like this:
<property name="id" xpath="//Atom:entry/Atom:id" disAtt="" mediaType="txt,pix" isSingleSelection="true" />
the attValues contains mediaTypes:
"txt" OR "vid" etc
I need to get all the properties that have mediaType of type txt or vid
Note: I can get the mediaType like this:
dynObject[0].property.mediaType.Value;
Looks backwards, In the first example you want a specific attribute where it's value contains one of a list, In the second example you show code getting any attribute whose value is contained by one of your list.
Assuming attValues is a list of values to search for
return new DynamicXml(from item in _elements
where attValues.Any(v => item.Attribute("attName").Value.Contains(v))
select item);

Return every item in a list from a foreach

List<object> li = new List <object>(Items);
string name = "";
foreach (var item in Items)
{
name = item["title"].ToString();
}
return name;
Using this code snippet, I can't find a way for to change the return to output all items from the list. As is, it only returns the last item. How can I get every item returned?
You have to return a new list, in your example you're just setting name to the current name then returning name at the end. Since you loop through all the elements name is set to the final value in the list before returning. Besides that, your return type is string unless you concatinate all the elements in li into a single string then you can't return a list as a string.
List<string> newList = li.Select(x => x["title"].ToString()).ToList();
Will create a new list of strings where each element is the title of an element from your source list, li.
If you really want to return a string you can use (I believe) String.Join or, (this one I'm certain of) Aggregate like so;
return li.Aggregate((c, n) => c["title"].ToString() + ", " + b["title"].ToString());
The above code will return string that is a comma separated list of the elements titles.
This is a little rediculous for just returning a list but it works. I would personally just return the whole thing at once.
List<object> li = new List <object>(Items);
string name = "";
foreach (var item in Items)
{
yield return item["title"].ToString();
}
As you know, method can returns one value with return statement. So you shoud to return all items as IEnumerable (List, Array, etc).
return Items.Select(x => x["Title"].ToString()).ToArray();
You need to return the whole List and extract each element when you want to use them. You cannot pass all these elements at once unless you store them in some sort of container (an array, for example.)
Again, this does not make much sense if you already have a List object to house them. The CLR's List<T> type is an adjustable length array, not the classic linked list.
If you can post more detail as to what your exact scenario is, we can help you better.

Categories

Resources