How would like to to compare values in this nested foreach.
I want to compare and if they match print YES for example.
Cheers
using System;
class Program
{
static void Main()
{
// Use a string array to loop over.
string[] ferns =
{
"apple",
"Equisetopsida",
"Marattiopsida",
"Polypodiopsida"
};
string[] fruits=
{
"apple",
"mango",
"Marattiopsida",
"Polypodiopsida"
};
// Loop with the foreach keyword.
foreach (string value in ferns)
{
Console.WriteLine(value);
foreach (string value in fruits)
{
Console.WriteLine(value);
}
//I would like to compare values here.
//Compare frens values against fruits values.
//How can i achieve this
}
}
}
foreach (string fern in ferns)
{
Console.WriteLine(fern);
foreach (string fruit in fruits)
{
Console.WriteLine(fruit);
if(fruit.Equals(fern))
Console.WriteLine("YES");
}
}
value is not a keyword here(through it is in some circumstances). All you have to do is pick whatever variable name you like
Do you want to compare them to see if they match in order? Or just if one list contains the other one at all?
If order counts, loop through both at same time with counter variable (just needs boundary checks):
for (int x = 0; x < ferns.Length; x++)
{
if (ferns[x] == fruits[x])
{
Console.WriteLine("YES!");
}
}
If it just needs to contain it:
foreach (string fern in ferns)
{
if (fruits.Contains(fern))
Console.WriteLine("YES!");
}
This would also be a good place to use an intersection. An intersection takes two lists and returns all the items that 'both' lists have in common.
IEnumerable<string> commonWords = ferns.Intersect(fruits);
Option A
foreach (string fernsvalue in ferns)
{
foreach (string fruitsvalue in fruits)
{
if (fernsvalue.Equals(fruitsvalue))
Console.WriteLine("They are equal");
}
}
Option B
List<string> fernsList = new List<string>(ferns.Length);
List<string> fruitsList = new List<string>(fruits.Length);
fernsList.AddRange(ferns);
fruitsList.AddRange(fruits);
List<string> Differences = fernsList.Except(fruitsList).ToList();
Option C
bool equal = ferns.SequenceEqual(fruits); //compares for exact equality
first of all, in each of yours foreach, current element has this same name, and you will not be able to reach botch of them in second foreach.
To compare two string, you can use String.Compare method. For example:
foreach (string fern in ferns)
{
foreach (string fruit in fruits)
{
if(String.Compare(fern,fruit,false)==0)
{
Console.WriteLine("YES");
}
}
}
Are you trying to see if the elements in the arrays fruits and ferns match at the same index? If so then a nested foreach loop isn't the best way to achieve this. It's much easier to use a for loop
for (int i = 0; i < ferns.Length && i < fruits.Length; i++) {
if (fruits[i] == ferns[i]) {
Console.WriteLine("{0} YES!!!", fruits[i]);
}
}
If instead you're looking to see if there is any match at all for an element in the ferns array in the fruits array then you could try the following
foreach (string fern in ferns) {
Console.Write("{0} ", fern);
bool isMatch = false;
foreach (string fruit in fruits) {
if (fruit == fern) {
isMatch = true;
break;
}
}
Console.WriteLine(isMatch ? "YES" : "NO");
}
Related
I am working on a program which needs to enter values in an array in a loop. I need a way to find the largest index:
string[] stuff = { "Headphones", "Pen", "stapler" };
string[] alreadysaid = { "Headphones" };
foreach (string stuffs in stuff)
{
if (alreadysaid.Contains(stuffs))
{
Console.WriteLine("already said");
}
else
{
Console.WriteLine(stuffs);
// add said element to alreadysaid
}
}
I suggest using HashSet<string> instead of string[] for alreadysaid; now all you have to do is to Add the stuffs:
HashSet<string> alreadysaid = new HashSet<string>() { "Headphones" };
foreach (string stuffs in stuff)
{
if (alreadysaid.Add(stuffs))
{
Console.WriteLine(stuffs);
}
else
{
Console.WriteLine("already said");
}
}
Whenever you want to get alreadysaid as an string[] you can use Linq:
string[] arraySaid = alreadysaid.ToArray();
Use LINQ to do that
int maxIndex = stuff.ToList().IndexOf(stuff.Max());
I have this code:
foreach (var row in App.cardSetWithWordCounts)
{
details.Children.Add(new SeparatorTemplate());
// do some tasks for every row
// in this part of the loop ...
}
I would like to not do the adding of a SeparatorTemplate BUT I would like to do the other tasks on the first run of the foreach. Does anyone have a suggestion on how I can do this?
I want to execute the rest of the code in the foreach but not the line adding the template on the first time around.
If you want to skip the first row, you can use Skip:
foreach (var row in App.cardSetWithWordCounts.Skip(1))
If you want to know the exact row number, use the Select overload:
foreach (var x in App.cardSetWithWordCounts.Select((r, i) => new { Row = r, Index = i })
{
// use x.Row and x.Index
}
The simpliest would be:
bool isFirstRun = true;
foreach (var row in App.cardSetWithWordCounts)
{
if(isFirstRun)
isFirstRun = false;
else
details.Children.Add(new SeparatorTemplate());
// do some tasks for every row
// in this part of the loop ...
}
You can use Skip method for this purpose:
foreach (var row in App.cardSetWithWordCounts.Skip(1))
Update:
foreach (var row in App.cardSetWithWordCounts.Select((c, index) => new { Row = c, Index = index })
{
if(row.Index != 0)
}
Just don't forget to add the following line to your using directives:
using System.Linq;
You can try to create an Extention method.
Action second parameter is the iterator index.
public static class ExtenstionArray
{
public static void ForEach<T>(this IEnumerable<T> sequence, Action< T, int> action)
{
int i = 0;
foreach (T item in sequence)
{
action(item,i);
i++;
}
}
}
Then use like this.
App.cardSetWithWordCounts.ForEach((i, idx)=>{
if(idx == 0){
details.Children.Add(new SeparatorTemplate());
}
// other logic
});
c# online
var firstRow = true;
foreach(var row in App.cardSetWithWordCounts)
{
if(firstRow)
{
firstRow = false;
}
else
{
// rest of the code here
}
}
How would you check multiple RichTextboxes containing multiple lines for unique and or duplicate lines. I've figured out how to loop through the richTextboxes and get the data, but I'm struggling on the logic to see if it's unique. My apologies if code is as clear as mud.
List<string> DistinctItems = new List<string>();
List<string> DupilcatedItems = new List<string>();
List<string> FirstItemsList = new List<string>();
List<string> CompareItemsList = new List<string>();
int ElementIndex = 0;
foreach (RichTextBox c in tableLayoutPanel1.Controls)
{
if (c.Text != null)
{
FirstItemsList.Add(c.Text.Replace("\n", Environment.NewLine).ToString());
if (CompareItemsList.Count == 0)
{
//Have to add the first batch
foreach (string str in FirstItemsList)
{
txtMixerTextBox.AppendText(str);
txtDistinctItems.AppendText(str);
DistinctItems.Add(str);
ElementIndex++;
}
CompareItemsList.Add(c.Text.Replace("\n", Environment.NewLine).ToString());
if (CompareItemsList.Count() > 0)
{
//OK we've gone through the first set
foreach (string s in CompareItemsList)
{
if (DistinctItems.Contains(s))
{
//It's a duplicate see if it's in the duplicate list
if (DupilcatedItems.Contains(s))
{
//OK it's in the list we don't have to add it
//See if it's in the textbox
if (!txtDuplicateItems.Text.Contains(s))
{
//OK it's not in the textbox let's add it
txtDuplicateItems.AppendText(s);
}
}
}
else
{
//It's not there so add it
DupilcatedItems.Add(s);
//now see if it's in the Distinct Textbox
if (!txtDistinctItems.Text.Contains(s))
{
//add it
txtDistinctItems.AppendText(s);
}
txtMixerTextBox.AppendText(s);
}
}
}
}
}
}
Use String.Split.
For example:
foreach (RichTextBox c in tableLayoutPanel1.Controls)
{
if (!c.Text.IsNullOrWhiteSpace)
{
string[] lines = c.Text.Split('\n');
string[] uniqueLines = GetUniqueLines(lines);//Some line-uniqueness checking algorithm
c.Text = String.Join('\n',uniqueLines)
}
}
This is what I did to get the results I was after. Looping through the RichTextboxes as noted above, I wrote the list to a file, stripped out the blank lines (where they came from I haven't the foggiest), read the file into a new list and then got the distinct list from there. I think the blank lines may have been messing me up, or it might have been the fact that I was looping through the strings in the list (again) thus giving myself duplicates. I'll likely get hammered for it, but it worked for me.
List<string> SortingList = new List<string>();
using (StreamReader r = new StreamReader("DistinctItemsNoBlankLines.txt"))
{
string line;
while ((line = r.ReadLine()) != null)
{
SortingList.Add(line);
}
}
List<string>DistinctSortingList = SortingList.Distinct().ToList();
foreach (string str in DistinctSortingList)
{
int index = 0;
while ( index < DistinctSortingList.Count() -1)
{
if (DistinctSortingList[index] == DistinctSortingList[index + 1])
DistinctSortingList.RemoveAt(index);
else
index++;
}
}
txtDistinctItems.Lines = DistinctSortingList.ToArray();
I would like to create a method which collect custom childnode values from an xml file and rewrite whit datas from a form. I had an idea thet I collect the datas in an ArrayList and give it to the method. But I cant change it in a foreach, because it throws ArgumentOutOfRangeException( although the ArraList contains 8 elements and the incremental variable's value also 8). So I would ask for help.
Here is the Code:
public static void Search(ArrayList nodeIds, ArrayList values)
{
XDocument doc = XDocument.Load("Options.xml");
int i = 0;
foreach (XElement option in doc.Descendants("BasicOptions"))
{
foreach(string nodeId in nodeIds)
{
if (option.Attribute("id").Value == nodeId)
{
foreach (XElement prop in option.Nodes())
{
prop.Value = values[i].ToString();
i++;
}
}
}
}
doc.Save("Options.xml");
}
It seems to me that i will go out of range without question because it is declared externally to 3 foreach statements and used within the center foreach. You should rethink your approach.
I suggest, but without knowing your incoming values or why your calling this, to redclare your internal foreach as a for statement like the following:
public static void Search(ArrayList nodeIds, ArrayList values)
{
XDocument doc = XDocument.Load("Options.xml");
foreach (XElement option in doc.Descendants("BasicOptions"))
{
foreach (string nodeId in nodeIds)
{
if (option.Attribute("id").Value == nodeId)
{
var nodes = option.Nodes().ToList();
for (int i = 0; i < nodes.Count && i < values.Count; i++)
{
XElement node = (XElement)nodes[i];
node.Value = values[i].ToString();
}
}
}
}
doc.Save("Options.xml");
}
Say I have a foreach loop.
I have to do something with the first object of the loop that I don't have to do with any of the other objects.
How do I check if the item that's currently in the loop is the first object.
I like the Linq way, but without the Skip(1), this way you can also use it for the last item in a list and your code remains clean imho :)
foreach(var item in items)
{
if (items.First()==item)
item.firstStuff();
else if (items.Last() == item)
item.lastStuff();
item.otherStuff();
}
There are several ways that you could do that.
Use a for loop instead
Set a Boolean flag
Use Linq to get the list.First() and then foreach over list.Skip(1)
Something like this:
bool first = true;
foreach(var item in items)
{
if (first)
{
item.firstStuff();
first = false;
}
item.otherStuff();
}
Here's a performant solution:
using (var erator = enumerable.GetEnumerator())
{
if (erator.MoveNext())
{
DoActionOnFirst(erator.Current);
while (erator.MoveNext())
DoActionOnOther(erator.Current);
}
}
EDIT: And here's a LINQ one:
if (enumerable.Any())
{
DoActionOnFirst(enumerable.First());
foreach (var item in enumerable.Skip(1))
DoActionOnOther(item);
}
EDIT: If the actions on the items have signatures assignable to Func<TItem, TResult>, you can do:
enumerable.Select((item, index) => index == 0 ? GetResultFromFirstItem(item) : GetResultFromOtherItem(item));
bool first = true;
foreach(var foo in bar)
{
if (first)
{
// do something to your first item
first = false;
}
// do something else to the rest
}
In my opinion this is the simplest way
foreach (var item in list)
{
if((list.IndexOf(item) == 0)
{
// first
}
// others
}
try this one
bool IsFirst = true;
foreach(DataRow dr in dt.Rows)
{
if (IsFirst)
{
// do some thing
IsFirst = false;
}
}
Can't think of anything but
var processedFirst = false;
foreach(var x in items) {
if(!processedFirst) {
ProcessFirst(x);
processedFirst = true;
}
This is more of a general solution for getting index along with each object in an array. Should work testing if it's the first.
List<String> entries = new List<string>();
entries.Add("zero");
entries.Add("one");
entries.Add("two");
Dictionary<int, String> numberedEntries = new Dictionary<int, string>();
int i = 0;
entries.ForEach(x => numberedEntries.Add(i++, x));
foreach (KeyValuePair<int, String> pair in numberedEntries) {
Console.WriteLine(pair.Key + ": " + pair.Value);
}
In this setup, the Key of the KeyValuePair is the index and the value is the object at that index, in my example a string, but any object could be placed there. It adds a little overhead, but can be used to determine any object in the list's index when needed.
You can also write:
foreach ((T item, bool isFirst) in items.Select((item, index) => (item, index == 0)))
{
if (isFirst)
{
...
}
else
{
...
}
}
If you need this a lot, you can write an extension method to replace the Select and make your code shorter.