Check elements in IEnumerable<string> sequence for specific string - c#

foreach (string s in diff.InSecondNotInFirst)
{
if (!s.Contains("some text"))
{
Assert.Fail();
}
}
Can I do this without the foreach? diff.InSecondNotInFirst is IEnumerable<string>.

With Linq you can do something like:
if (diff.InSecondNotInFirst.Any(s => !s.Contains("some text")))
Assert.Fail();

Related

Use enumerations extension methods to shorten code

I want to checkmark some listview items from a given array. How could the code below be shortend with enumeration extension methods.
foreach (Team SelectedTeam in value.Teams)
{
foreach (ListViewItem LVItem in TeamLstVw.Items)
{
Team Team = (Team)LVItem.Tag;
if (SelectedTeam.Equals(Team))
LVItem.Selected = true;
}
}
You could eradicate the outer foreach loop, by using Linq methods inside the inner foreach loop. In this case, you could just check if the current LVItem.Tag is contained inside value.Teams
foreach (ListViewItem LVItem in TeamLstVw.Items)
{
var Team = (Team)LVItem.Tag;
//I'd personally compare an identifier here. Like an Id property
//.Any(x => x.Id == Team.Id)
//Or use .Contains(): value.Teams.Contains(Team)
if(value.Teams.Any(x => x == Team)) {
LVItem.Selected = true;
}
}

Is there another way to get a property of a foreach loop item?

I have noticed that a lot of times I need to do something like this
foreach (SomeObject item in listOfItems)
{
string itemName = item.Name;
...
}
But I would much prefer if there was a way to do something like this:
foreach (string item.Name in listOfItems)
{
...
}
Is this possible in C#?
You can use LINQ:
foreach (string name in listOfItems.Select(item => item.Name))
{
// ...
}

How to use First() / FirstOrDefault()?

using System;
using System.Linq;
public class Program
{
public static void Main()
{
var flame = new string[]
{
"bad", "word"
}
;
var text = "this contains some bad words";
foreach (string item in text.Split(' '))
{
bool testerino = flame.Any(item.Contains);
if (testerino)
{
Console.WriteLine("1");
}
}
}
}
https://dotnetfiddle.net/Widget/as5iTs
I want Console.WriteLine("1"); to run only once. I tried to use First() and FirstOrDefault() but I was not able to use it without syntax errors. Why I'm using a Split? I don't know. It was the only way to get .Contains() running. I did receive errors using char item in text with Contains().
I don't need to use foreach or even First() it is just only way I know so far.
Any help is very much appreciated.
You want something like this:
var anyFlameWords =
text
.Split(' ')
.Any(word => flame.Contains(word));
if (anyFlameWords)
Console.WriteLine("1");
You don't need First/FirstOrDefault, unless you want the first element from the collection, which looking at your existing code is not what you require.
You can break after you act on the first match.
foreach (string item in text.Split(' '))
{
bool testerino = flame.Any(item.Contains);
if (testerino)
{
Console.WriteLine("1");
break;
}
}
But a more concise alternative is just
if (test.Split(' ').Any(f=>flame.Contains(f))) Console.WriteLine("1");
If you are interested to see how IEnumerable<T>.FirstOrDefault could be used here, note that you can pass in a predicate to FirstOrDefault to get the first item in the IEnumerable<T> that matches that predicate (or the default value for T if nothing matches):
var firstMatch = test.Split(' ').FirstOrDefault(w=>flame.Contains(w));
if (firstMatch != null) Console.WriteLine("1");
Just add a break; to your if-case:
foreach (string item in text.Split(' '))
{
bool testerino = flame.Any(item.Contains);
if (testerino)
{
Console.WriteLine("1");
break;
}
}
A break causes to exit the foreach-loop immediately.
This linq may help
bool badWordExists = text.Split(' ').Any(s => flame.Contains(s));
if(badWordExists) Console.WriteLine("1");

C# Load items from file and split into array

HI guys i'm trying to load the contents of my file "item.ids" which currently holds this:
1:Stone
2:Grass
3:Dirt
I want to read each line the the file and split it at the ":". I am using the following code:
foreach(String line in File.ReadAllLines("item.ids")) {
items = line.Split(':');
}
foreach (String part in items)
{
addToList(specs, part);
}
}
public void addToArray(Array array, int index, String s)
{
try
{
array.SetValue(s, index);
}
catch (Exception ex)
{
addToList(specs, ex.ToString());
}
}
public void addToList(ListBox listbox, String s)
{
listbox.Items.Add(s);
}
This works but it only does the last line so it will output it like so:
3
dirt
If you could help me along with my code it would be very helpful.
You need to fill the list after every read.
foreach(String line in File.ReadAllLines("item.ids"))
{
items = line.Split(':');
foreach (String part in items)
{
addToList(specs, part);
}
}
... otherwise you're only ever adding the last item by default.
In the 1st loop you set the item field each time you iterate so when you exit the loop it will be set to the last value. You probably want to change to something like this:
foreach(String line in File.ReadAllLines("item.ids"))
{
foreach (String part in line.Split(':'))
{
addToList(specs, part);
}
}
You've closed your loop to early so items will only contain the last iteration
change your code to:
foreach(String line in File.ReadAllLines("item.ids"))
{
items = line.Split(':');
foreach (String part in items)
{
addToList(specs, part);
}
}

Performing a boolean AND string search on sub-collections of a collection (non-LINQ)

I hope the title makes sense.
I have a set of items that I want to search and select a subset of, based on a set of keywords that must all appear at least once in any of the SubItems of the Items. I believe this could easily be achieved using LINQ, but I'm using .NET 2.0 for this project.
The code below should achieve pretty much what I want to do, assuming AllBitsAreSet is implemented, but I'm wondering if I'm missing an alternative, simpler way of doing this?
Since there doesn't appear to be a good way of checking if all the bits in a BitArray are set, besides looping through them all (please tell me if there is!), I'm wondering about "nicer" alternatives. Not necessarily more CPU efficient, because I doubt the below code will be too slow for the data sets I'm working with, but ones with less code.
public List<Item> Search(Item[] items, List<string> keywords)
{
List<Item> results = new List<Item>();
BitArray flags = new BitArray(keywords.Count);
foreach (Item item in items)
{
flags.SetAll(false);
foreach (SubItem subItem in item.SubItems)
{
for (int i = 0; i < keywords.Count; i++)
{
if (subItem.StringValue.IndexOf(keywords[i]) >= 0)
flags[i] = true;
}
}
if (AllBitsAreSet(flags)) results.Add(item);
}
return results;
}
You can use LINQ Bridge to get LINQ support on .NET 2.0 and use the following LINQ query.
items.Where(i =>
keywords.All(k =>
i.SubItems.Any(s =>
s.StringValue.Contains(k))));
You can avoid using the bit set if you swap the two inner loops - the performance impact depends on thenumber of sub items vs the number of keywords.
foreach (Item item in items)
{
Boolean found = false;
foreach (String keyword in keywords)
{
found = false;
foreach (SubItem subItem in item.SubItems)
{
if (subItem.StringValue.Contains(keyword))
{
found = true;
break;
}
}
if (!found)
{
break;
}
}
if (found)
{
result.Add(item);
}
}
I would write it as follows. Of course this is very similar to Daniel's solution, but I believe it is better.
public List<Item> Search(Item[] items, List<string> keywords)
{
List<Item> results = new List<Item>();
foreach (Item item in items)
if(ContainsAllKeywords(item, keywords))
results.Add(item);
return results;
}
bool ContainsAllKeywords(Item item, List<string> keywords)
{
foreach (string keyword in keywords)
if (!ContainsKey(item.SubItems, keyword))
return false;
return true;
}
bool ContainsKey(IEnumerable<SubItem> subItems, string key)
{
foreach (SubItem subItem in subItems)
if (subItem.StringValue.Contains(key))
return true;
return false;
}
edit: changed == to .Contains() as per comment

Categories

Resources