How to compare ItemElements of a Radcombobox with an expected string? - c#

I need compare if a Radcombobox has ItemElements that matches with my expected string. Here is what I'm trying to do:
foreach (IRadComboBoxItem item in comboBox.ItemElements)
{
var itemExists = comboBox.ItemElements.FirstOrDefault(items => item.Text.Contains(expectedString));
if (itemExists == null) continue;
itemExists.Select();
return true;
}
However comboBox.Text.Contains(expectedString) is not supported as I'm comparing IRadComboBoxItem with a string. Could you please suggest how to achieve this?

Use linq method of Any:
return comboBox.ItemElements.Any(item => item.Text.Contains(expectedString));
In your above code you mixed a bit the use of different linq methods
In the FirstOrDefault - it returns the first item in a collection that matches a predicate, otherwise default(T).
Then if it is not null you perform an Select but assign it to nowhere.
You have this code in a foreach loop - but do not use the item nowhere. you don't need the loop because you are trying to use the linq methods (which behind the scenes use the loops themselves)
Following comment what you want is:
var wantedItem = comboBox.ItemElements.FirstOrDefault(item => item.Text.Contains(expectedString));
if(wantedItem != null)
{
//What you want to do with item
}
Didn't work with RadComboBox myself but by this site maybe:
RadComboBoxItem item = comboBox.FindItemByText(expectedString);
I assume that if it doesn't find it returns null

Related

Function to linq conversion

I have a function which I believe can be simplified into LINQ but have been unable to do so yet.
The function looks like this:
private IList<Colour> GetDifference(IList<Colour> firstList, IList<Colour> secondList)
{
// Create a new list
var list = new List<Colour>();
// Loop through the first list
foreach (var first in firstList)
{
// Create a boolean and set to false
var found = false;
// Loop through the second list
foreach (var second in secondList)
{
// If the first item id is the same as the second item id
if (first.Id == second.Id)
{
// Mark it has being found
found = true;
}
}
// After we have looped through the second list, if we haven't found a match
if (!found)
{
// Add the item to our list
list.Add(first);
}
}
// Return our differences
return list;
}
Can this be converted to a LINQ expression easily?
What is Colour? If it overrides Equals to compare by Id then this would work:
firstList.Except(secondList);
If Colour does not override Equals or it would be wrong for you to do so in the wider context, you could implement an IEqualityComparer<Colour> and pass this as a parameter:
firstList.Except(secondList, comparer);
See the documentation
As noted in the comments below, Except has the added side effect of removing any duplicates in the source (firstList in this example). This may or may not be an issue to you, but should be considered.
If keeping any duplicates in firstList is of importance, then this is the alternative:
var secondSet = new HashSet<Colour>(secondList, comparer);
var result = firstList.Where(c => !secondSet.Contains(c));
As before, comparer is optional if Colour implements appropriate equality
try the following:
var result = firstList.Where(x => !secondList.Any(y => y.ID == x.ID));
Edit:
If you care about runtime and don't mind creating your own IEqualityComparer<>, i would suggest you use Except like Charles suggested in his answer. Except seems to use a hashtable for the second list which speeds it up quite a bit compared to my O(n*m) query. However be aware that Except removes duplicates from secondList as well.

How to find last occurrence of an element using FindLast()

I want to find the last occurrence of an element in a list and know I must use the FindLast() to do that. However, I don't know how to implement and use this method.
Here is the code that I have:
// the list I need to check
orderedMetricsByNS = (List<Metric>) lmresponse.Metrics.OrderBy(metric => metric.Namespace);
foreach (Metric m in orderedMetricsByNS)
{
// want to use the FindLast() here
}
How do I retrieve the last occurrence of a metric like this? Thanks
What is the Predicate? You can use it like this:
var item = orderedMetricsByNS.FindLast(m => /* your condition */);
Or if you wanna just find the last item use Last method
var item = orderedMetricsByNS.Last();
Btw you can't cast from IOrderedEnumerable<T> to List<T>, your code will fail, you need to use ToList method.
orderedMetricsByNS = lmresponse.Metrics.OrderBy(metric => metric.Namespace).ToList();
You can use LINQ:
var last = orderedMetricByNS.LastOrDefault();
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.lastordefault%28v=vs.95%29.aspx

How to check for object of particular type in a HashSet in windows 8?

I have a HashSet of generic type UserControl, which can have various UserControl (login, settings). I want to check whether the set contains object of any particular type (say login). If so i want to get that element.
I know its quite easy to do with a loop, but is there any better way?
Unfortunately, you cannot do it without a loop, because you need to try all elements of your collection to check their types. In fact, it does not matter that you have a hash set: it would work the same with a list, or any other enumerable. However, LINQ lets you hide the loop, like this:
var item = hashSet.OfType<DesiredType>().FirstOrDefault();
As #dasblinkenlight says you can use OfType<T>() LINQ method to hide the loop. His answer also uses FirstOrDefault() method so "contains element?" questions is rephrased to "is not null". Another way is to use Count() > 0 after OfType<T>().
var items = hashSet.OfType<DesiredType>();
if (items.Count() > 0) {
DesiredType item = items.First();
...
}
Third way is to put predicate in the FirstOrDefault() method.
var item = hashSet.FirstOrDefault(x =>
x.getType() == typeof(DesiredType)
);
if (item != null) {
...
}
If your set doesn't change that often, you can use GroupBy(func) to reduce computation complexity to O(1). Idea is to build dictionary once and query it instead.
var groups = new Dictionary<Type, IEnumerable<UserControl>>();
foreach(var group in hashSet.GroupBy(x => x.GetType()))
groups.Add(group.Key, group);
.
.
.
if (groups.ContainsKey(typeof(DesiredType)) {
DesiredType item = items.First();
...
}

How to access a particular data in LINQ query result?

I know, this is very simple for you guys.
Please consider the following code:
string[] str = { "dataReader", "dataTable", "gridView", "textBox", "bool" };
var s = from n in str
where n.StartsWith("data")
select n;
foreach (var x in s)
{
Console.WriteLine(x.ToString());
}
Console.ReadLine();
Supposedly, it will print:
dataReader
dataTable
right?
What if for example I don't know the data, and what the results of the query will be (but I'm sure it will return some results) and I just want to print the second item that will be produced by the query, what should my code be instead of using foreach?
Is there something like array-indexing here?
You're looking forEnumerable.ElementAt.
var secondMatch = str.Where(item => item.StartsWith("data")) //consider null-test
.ElementAt(1);
Console.WriteLine(secondMatch); //ToString() is redundant
SinceWherestreams its results, this will be efficient - enumeration of the source sequence will be discontinued after the second match (the one you're interested in) has been found.
If you find that the implicit guarantee you have that the source will contain two matches is not valid, you can use ElementAtOrDefault.
var secondMatch = str.Where(item => item.StartsWith("data"))
.ElementAtOrDefault(1);
if(secondMatch == null) // because default(string) == null
{
// There are no matches or just a single match..
}
else
{
// Second match found..
}
You could use array-indexing here as you say, but only after you load the results into... an array. This will of course mean that the entire source sequence has to be enumerated and the matches loaded into the array, so it's a bit of a waste if you are only interested in the second match.
var secondMatch = str.Where(item => item.StartsWith("data"))
.ToArray()[1]; //ElementAt will will work too
you got a few options:
s.Skip(1).First();
s.ElementAt(1);
The first is more suited for scenarios where you want X elements but after the y first elements. The second is more clear when you just need a single element on a specific location

Explain this LINQ code?

I asked a question in which one of the response contained the following LINQ code:
var selected = lstAvailableColors.Cast<ListItem>().Where(i => i.Selected).ToList();
selected.ForEach( x => { lstSelectedColors.Items.Add(x); });
selected.ForEach( x => { lstAvailableColors.Items.Remove(x);});
Can someone explain the above LINQ to a total newbie?
The LINQ operators use what's called a fluent interface, so you can read the first line as a series of function calls. Assuming that lstAvailableColors is IEnumerable<T>, the idea is that each available color flows through the LINQ operators.
Let's break it down:
var selected = lstAvailableColors
// each item is cast to ListItem type
.Cast<ListItem>()
// items that don't pass the test (Selected == true) are dropped
.Where(i => i.Selected)
// turn the stream into a List<ListItem> object
.ToList();
EDIT: As JaredPar pointed out, the last line above (ToList()) is very important. If you didn't do this, then each of the two selected.ForEach calls would re-run the query. This is called deferred execution and is an important part of LINQ.
You could rewrite this first line like this:
var selected = new List<ListItem>();
foreach (var item in lstAvailableColors)
{
var listItem = (ListItem)item;
if (!listItem.Selected)
continue;
selected.Add(listItem);
}
The last two lines are just another way to write a foreach loop and could be rewritten as:
foreach (var x in selected)
{
lstSelectedColors.Items.Add(x);
}
foreach (var x in selected)
{
lstAvailableColors.Items.Remove(X);
}
Probably the hardest part of learning LINQ is learning the flow of data and the syntax of lambda expressions.
Explanation from original question.
The LINQ version works in two parts. The first part is the first line which finds the currently selected items and stores the value in a List. It's very important that the line contain the .ToList() call because that forces the query to execute immediately vs. being delayed executed.
The next two lines iterate through each value which is selected and remove or add it to the appropriate list. Because the selected list is already stored we are no longer enumerating the collection when we modify it.
It casts each item in the list to type ListItem, then selects only those whose Selected property is true. It then creates a new list containing just these items. For each item in the resulting list, it adds that item to the selected colors list and removes it from the available colors list.
Maybe some translations would help
var selected = lstAvailableColors.Cast<ListItem>().Where(i => i.Selected).ToList();
could be written as:
List<ListItem> selected = new List<ListItem>();
foreach (ListItem item in lstAvailableColors)
{
if (item.Selected)
selected.Add(item);
}
Note that foreach implicitly casts the items on the list to whatever type the loop variable is, in this case ListItem, so that takes care of the Cast<ListItem> on the list. Where filters out any items for which the expression is false, so I do the same thing with an if statement. Finally, ToList turns the sequence into a list, so I just build up a list as I go. The end result is the same.
And:
selected.ForEach( x => { lstSelectedColors.Items.Add(x); });
selected.ForEach( x => { lstAvailableColors.Items.Remove(x); });
could be written as:
foreach (ListItem item in selected)
{
lstSelectedColors.Items.Add(item);
lstAvailableColors.Items.Remove(item);
}
I doubt if there's a good reason for writing it the more obscure way in that case.

Categories

Resources