Checking if a string is in an ObservableCollection of Tuple - c#

I have an ObservableCollection as shown below:
ObservableCollection<Tuple<Guid, string>> _taskCollection
I want to write some code that will check if a given string exists in the collection. The string is held in “TaskName” and the code I wrote looks like this:
_taskCollection.Select(x => x.Item2 == TaskName.Trim()).Any()
The problem I have is that this line of code always returns “true” regardless of whether the value in “TaskName” is in one of the Tuple’s or not. Can anyone show me what I am missing?

You should use Any directly rather than after Select:
_taskCollection.Any(x => x.Item2 == TaskName.Trim())
This code:
_taskCollection.Select(x => x.Item2 == TaskName.Trim())
will return a list of bool which has length equivalent with _taskCollection, so then you call Any, it's always true

Select transforms N input items into N output items. The amount of items doesn't change here.
What you want is to filter the items. That's what Where is for.
Using Where your second query would have been correct:
_taskCollection.Where(x => x.Item2 == TaskName.Trim()).Any();
That can be shortened to the following:
_taskCollection.Any(x => x.Item2 == TaskName.Trim());
The reason is that Any provides an overload that accepts a condition.
And I think it really reads intuitivly: "Is there Any item in _taskCollection for which Item2 == TaskName.Trim()?"

Related

Build predicate with lis in parameter

I need to filter a list on multiple value.
It works well with basic type like string but I need to filter on 2 others filters build on list like that :
predicate.And(i => i.countries.Find(c => c.Code == country).Code == country)
First of all I'm not sure it is the good way to build this sort of predicate.
Second when predicate is built it looks like that :
{i => (i.countries.Find(c => (c.Code == value(Portail.Controllers.ProfilsController+<>c__DisplayClass21_0).country)).Code == value(Portail.Controllers.ProfilsController+<>c__DisplayClass21_0).country)}
And of course it doesnt work.
Is it possible to do such a thing and if yes, how?

Linq: Removing Group By but still get its items?

Just some details. Get Records is a variable where it contains the results of my stored procedure. Now, what I want to ask is what if I want to remove the group by function but I still want to get the key and items? Is there a way to do it?
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName && x.MovieName != null)
.GroupBy(x => x.MovieName,
(key, elements) =>
new
{
Id = key,
Items = elements.ToList()
}).ToList();
There's no need for GroupBy here since you are looking for a specific movieName.
I guess you wanted something like this:
var sortResCinema = GetRecords.Where(x => test2.branch == x.Bbranch && test.movieName == x.MovieName).ToList();
You can replace the GroupBy with a Select. The Select statement can be used to alter the type of the results returned, which is what you appear to want to do. Should work with exactly the same syntax as the second parameter. So replace "GroupBy" with "Select" and remove the first argument. The key and elements properties that are being used in the GroupBy statement are internal to that function so you'd need to work out what function you want to replace these by, for instance the key might be x.MovieName.

why cant I compare two id's in c#

I tried to compare two ids and get some result.it works for other strings.but not for this.
I tried like this.
var neededData = mainFaires.Where(c => c.trimacid == passId );
in here passId= OX20160330HAVHAV
and in the mainFaires list, in somewhere it includes this id.but it didn't give the result.I found in here
var x = mainFaires.ElementAt(27261);
this list include the same id.but didn't give result.I can't think why.
ElementAt is find the position.
You should use select to find the records
var x = mainFaires.Select(o => o.trimacid == 27261);
You should use .ToList() .First() or .FirstOrDefault() to actually commit the query and get a result. Your code only defined the query, but didn't actually submit it to the data collection.
If you expect only one item as a result, you're code should look like this:
var neededData = mainFaires.Where(c => c.trimacid == passId ).FirstOrDefault();
If there was no item found, neededData would be NULL or whatever the default value is. You may also check the Documentation here https://msdn.microsoft.com/en-us/library/system.linq.enumerable%28v=vs.100%29.aspx

Filter in linq with ID's in a List<int>

I need do a filter that request data with a parameter included in a list.
if (filter.Sc.Count > 0)
socios.Where(s => filter.Sc.Contains(s.ScID));
I try on this way but this not work, I tried also...
socios.Where( s => filter.Sc.All(f => f == s.ScID));
How I can do a filter like this?
socios.Where(s => filter.Sc.Contains(s.ScID));
returns a filtered query. It does not modify the query. You are ignoring the returned value. You need something like:
socios = socios.Where(s => filter.Sc.Contains(s.ScID));
but depending on the type of socios the exact syntax may be different.
In addition to needing to use the return value of your LINQ .Where(), you have a potential logic error in your second statement. The equivalent logic for a .Contains() is checking if Any of the elements pass the match criteria. In your case, the second statement would be
var filteredSocios = socios.Where( s => filter.Sc.Any(f => f == s.ScID));
Of course if you can compare object-to-object directly, the .Contains() is still adequate as long as you remember to use the return value.

and operator in Linq and select distinct values using linq

I am new to .net. I have a form in which there are two comboboxes cbProduct and cbBrandName and also a label lblPrice.
I am trying to implement the below code but it is showing blue scribbles to &&.
(Error: operator '&&' cannot be applied to operands of type 'lambda expression' and 'lambda expression')
I tried the below code: (not working)
lblPrice.Text = string.Empty;
lblPrice.Text = doc.Descendants("items"
).Where((x => x.Element("productname"
).Value.Equals(cbProduct.SelectedItem.ToString())) && /*blue scribbles to '&&'*/
(y => y.Element("brandname").Value.Equals(cbBrandName.SelectedItem.ToString()
))).Select(k => k.Element("price"
).Value).ToString();
My other question is that i want to make the selected values of cbProduct as distinct. The below code takes all the values instead of distinct values:
cbProduct.Items.AddRange(doc.Descendants("items"
).Select(x => x.Element("productname").Value
).ToArray<string>());//adds all products
cbProduct.SelectedIndex = 0;
giving any one answer is ok
Please assist me
Thanks in advance
It looks like you are passing 2 lambdas to the Where function and trying to logical-and (&&) them together. You can't do that. The && has to occur inside the Where lambda. Or you can chain 2 Where functions together. Something like this:
lblPrice.Text = doc.Descendants("items")
.Where(x => x.Element("productname").Value.Equals(cbProduct.SelectedItem.ToString()) &&
x.Element("brandname").Value.Equals(cbBrandName.SelectedItem.ToString()))
.Select(k => k.Element("price").Value).ToString();
The other issue I see is you are ending your query with a select, but never actually enumerating it. You probably want to do something like this:
lblPrice.Text = doc.Descendants("items")
.Where(x => x.Element("productname").Value.Equals(cbProduct.SelectedItem.ToString()) &&
x.Element("brandname").Value.Equals(cbBrandName.SelectedItem.ToString()))
.Select(k => k.Element("price").Value)
.FirstOrDefault();
Which will return the string you are looking for, or null if nothing exists (so you probably want to skip the final .ToString() call in this case, since you are already returning a string from Select and .ToString() on a null will throw an exception).
For the first question, it looks like you just want to select the one price. This code will work, assuming that the item is found by the .Single(). It will throw otherwise, in which case you should use .SingleOrDefault() and check for null on the found item.
lblPrice.Text =
doc.Descendants("items")
.Single(x => x.Element("productname").Value == cbProduct.SelectedItem.ToString() &&
x.Element("brandname").Value == cbBrandName.SelectedItem.ToString())
.Element("price").Value;
For the second question, you need to close off your .Select with a bracket, then you can call .Distinct() and .ToArray() to filter to distincts and project the result to string[]. I've also thrown an .OrderBy() in there, as there's nothing more annoying than a ComboBox in a random order. Try this:
cbProduct.Items.AddRange(doc.Descendants("items")
.Select(item => item.Element("productname").Value)
.Distinct()
.OrderBy(item => item)
.ToArray());

Categories

Resources