I have a simple code, which send from server to clients value to count. This loop count for 9 value, from 1 to 9. Everything work good for 1,3 or 9 clients. But for other number of clients when i_wiersz has value 9 and foreach loop want sent something to another client server break down. Ho make, to work with any one numbers of clients?
I try put inside foreach loop:
if(i_wiersz == 9)
break;
but a get an error: Error
Control cannot leave the body of an anonymous method or lambda
expression
My code:
bool spr_wiersz(int wiersz, int kolumna) //chck_roow(int roow, int column)
{
wys_tab();
int i_wiersz = 0;
bool[] result = new bool[9];
while (i_wiersz < 9)
{
subscribers.ForEach(delegate(ImessageCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
result[i_wiersz] = callback.spr_wiersz(wiersz, kolumna, i_wiersz);
i_wiersz++;
}
});
for (int j = 0; j < i_wiersz; j++)
{
if (result[j] == false)
{
return false;
}
}
}
return true;
}
Can’t you simply convert it to a traditional foreach?
foreach (IMessageCallback callback in subscribers)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
result[i_wiersz] = callback.spr_wiersz(wiersz, kolumna, i_wiersz);
i_wiersz++;
if (i_wiersz == 9)
break;
}
}
Related
I want skip my in foreach. For example:
foreach(Times t in timeList)
{
if(t.Time == 20)
{
timeList.Skip(3);
}
}
I want "jump" 3 positions in my list.. If, in my if block t.Id = 10 after skip I want get t.Id = 13
How about this? If you use a for loop then you can just step the index forward as needed:
for (var x = 0; x < timeList.Length; x++)
{
if (timeList[x].Time == 20)
{
// option 1
x += 2; // 'x++' in the for loop will +1,
// we are adding +2 more to make it 3?
// option 2
// x += 3; // just add 3!
}
}
You can't modify an enumerable in-flight, as it were, like you could the index of a for loop; you must account for it up front. Fortunately there are several way to do this.
Here's one:
foreach(Times t in timeList.Where(t => t.Time < 20 || t.Time > 22))
{
}
There's also the .Skip() option, but to use it you must break the list into two separate enumerables and then rejoin them:
var times1 = timeList.TakeWhile(t => t.Time != 20);
var times2 = timeList.SkipeWhile(t => t.Time != 20).Skip(3);
foreach(var t in times1.Concat(times2))
{
}
But that's not exactly efficient, as it requires iterating over the first part of the sequence twice (and won't work at all for Read Once -style sequences). To fix this, you can make a custom enumerator:
public static IEnumerable<T> SkipAt<T>(this IEnumerable<T> items, Predicate<T> SkipTrigger, int SkipCount)
{
bool triggered = false;
int SkipsRemaining = 0;
var e = items.GetEnumerator();
while (e.MoveNext())
{
if (!triggered && SkipTrigger(e.Current))
{
triggered = true;
SkipsRemaining = SkipCount;
}
if (triggered)
{
SkipsRemaining--;
if (SkipsRemaining == 0) triggered = false;
}
else
{
yield return e.Current;
}
}
}
Then you could use it like this:
foreach(Times t in timeList.SkipAt(t => t.Times == 20, 3))
{
}
But again: you still need to decide about this up front, rather than inside the loop body.
For fun, I felt like adding an overload that uses another predicate to tell the enumerator when to resume:
public static IEnumerable<T> SkipAt<T>(this IEnumerable<T> items, Predicate<T> SkipTrigger, Predicate<T> ResumeTrigger)
{
bool triggered = false;
var e = items.GetEnumerator();
while (e.MoveNext())
{
if (!triggered && SkipTrigger(e.Current))
{
triggered = true;
}
if (triggered)
{
if (ResumeTrigger(e.Current)) triggered = false;
}
else
{
yield return e.Current;
}
}
}
You can use continue with some simple variables.
int skipCount = 0;
bool skip = false;
foreach (var x in myList)
{
if (skipCount == 3)
{
skip = false;
skipCount = 0;
}
if (x.time == 20)
{
skip = true;
skipCount = 0;
}
if (skip)
{
skipCount++;
continue;
}
// here you do whatever you don't want to skip
}
Or if you can use a for-loop, increase the index like this:
for (int i = 0; i < times.Count)
{
if (times[i].time == 20)
{
i += 2; // 2 + 1 loop increment
continue;
}
// here you do whatever you don't want to skip
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have an Infint class with one List field. In the main program, I want to read numbers (character by character) and add them to this list.
The assignment itself doesn't matter in this moment, what I'm wondering is why I can't add values to the list of the Infint object from the if/else block (inside the first while loop). I have initialised the List itself in the class constructor. I added the line number1.Number.Add(1) for debugging reasons, since the code wasn't working and I've come to realize it seems to be working fine outside that if/else block. I can't seem to find the solution.
Here are the following implementations:
internal class Infint
{
public bool isNegative { get; set; }
public List<int> Number { get; set; }
public Infint()
{
isNegative = false;
Number = new List<int>();
}
}
static void Main(string[] args)
{
using (StreamReader sr = new StreamReader("infint.txt"))
{
int i;
char num;
for (int operation = 0; operation < 3; operation++)
{
Infint number1 = new Infint();
Infint number2 = new Infint();
number1.Number.Add(1); //works
i = sr.Read();
while (sr.Peek() >= 0)
{
number1.Number.Add(1); //works
if (i == 10 || i == 13)
break;
num = (char)i;
if (operation == 0)
{
number1.Number.Add(1); //doesn't work
if (i == 45)
number1.isNegative = true;
else
{
number1.Number.Add(1); //doesn't work
//number1.Number.Add((int)Char.GetNumericValue(num));
}
}else if(operation == 1)
{
if (i == 45)
number2.isNegative = true;
else
{
number2.Number.Add((int)Char.GetNumericValue(num));
}
}else if(operation == 2)
{
Console.WriteLine("counts of num1: " + number1.Number.Count);
for (var k = 0; k < number1.Number.Count; k++)
{
Console.Write(number1.Number[k]);
}
Console.WriteLine("counts of num2: " + number2.Number.Count);
for (var k = 0; k < number2.Number.Count; k++)
{
Console.Write(number2.Number[k]);
}
}
i = sr.Read();
}
if (i == -1)
{
break;
}
//i = sr.Read();
}
}
Console.Read();
}
Removing the various noise in your code (it's extremely low quality, if you care), what you're left with is:
using var sr = new StreamReader("infint.txt");
for (int operation = 0; operation < 3; operation++)
{
var i = sr.Read();
while (sr.Peek() >= 0)
{
if (i == 10 || i == 13) break;
if (operation == 0)
{
// oh noes
}
}
}
So looking at the code and assuming what you describe is correct (if vague), that means that your text file starts with a new line, possibly two (you don't even mention your OS, let alone the contents of the file). If that is indeed the case, then it should be strikingly obvious why operation can't be 0 around the branch you're expecting it to be.
So i have two sorted lists with deliverable's and I want to Merge them. I never did this operation before and i can not really make it work. You can see method below that i wrote. I can not figure out while statement because it fires exception all the time. I dont know what to do...
public void MergeLists(List<Deliverable> a, List<Deliverable> b)
{
int index1 = 0;
int index2 = 0;
while (a.Count() >= index1 || b.Count() >= index2)
{
if (a[index1].ID> b[index2].ID)
{
FinalDeliverables.Add(a[index1]);
index1++;
}
else if (a[index1].ID < b[index2].ID)
{
FinalDeliverables.Add(a[index2]);
index2++;
}
else if (a[index1].ID == b[index2].ID)
{
FinalDeliverables.Add(a[index1]);
FinalDeliverables.Add(a[index2]);
index1++;
index2++;
}
}
}
I believe that the exceptions you are getting are coming from null pointers. This would occur if, for example, you already reached the end of one of the lists, yet your while loop is still trying to compare values. One workaround to this is to simply add a check before the if statements to see if one (or both) of the ends of the lists have been reached. If so, then simply add the remainder of the items from the other list.
public void MergeLists(List<Deliverable> a, List<Deliverable> b)
{
int index1 = 0;
int index2 = 0;
while (true)
{
// if the end of the 'a' list has been reached, then add
// everything from the 'b' list and break from the loop
if (index1 >= a.Count()) {
for (int i=index2; i < b.Count(); ++i) {
FinalDeliverables.Add(b[i]);
}
break;
}
// if the end of the 'b' list has been reached, then add
// everything from the 'a' list and break from the loop
if (index2 >= b.Count()) {
for (int i=index1; i < a.Count(); ++i) {
FinalDeliverables.Add(a[i]);
}
break;
}
if (a[index1].ID > b[index2].ID)
{
FinalDeliverables.Add(a[index1]);
index1++;
}
else if (a[index1].ID < b[index2].ID)
{
FinalDeliverables.Add(a[index2]);
index2++;
}
else if (a[index1].ID == b[index2].ID)
{
FinalDeliverables.Add(a[index1]);
FinalDeliverables.Add(a[index2]);
index1++;
index2++;
}
}
}
Note that a side effect of this refactor is that your original while loop no longer has to check boundaries. Instead, the loop will be terminated when one of the lists has been exhausted.
Also note that this solution assumes that your input lists are sorted in descending order.
You can use the LINQ Extension methods for this purpose, The Method signature for MergeLists will be like the following:
public void MergeLists(List<Deliverable> a, List<Deliverable> b)
{
var finalList = a.Concat(b);
List<Deliverable> FinalSortedList = finalList.OrderBy(x => x.ID).ToList();
}
Or else you can modify your own method as like the following: Before that Let me assume the following, The Count of elements in the Input list a will always be Greater than that of b. SO what you need to do is Check the count of elements before calling the method as well. So the call will be like the following:
if(a.Count>b.Count)
MergeLists(a,b);
else
MergeLists(b,a);
You mentioned that the two inputs ware sorted, Let me assume those lists are sorted in ascending order. Now consider the following code:
public void MergeLists(List<Deliverable> a, List<Deliverable> b)
{
int largeArrayCount = a.Count;
int currentBIndex = 0;
List<Deliverable> FinalResult = new List<Deliverable>();
for (int i = 0; i < largeArrayCount; i++)
{
if (i < b.Count)
{
if (a[i].ID >= b[i].ID)
{
// Add All elements of B Which is smaller than current element of A
while (a[i].ID <= b[currentBIndex].ID)
{
FinalResult.Add(b[currentBIndex++]);
}
}
else
{
FinalResult.Add(a[i]);
}
}
else
{
// No more elements in b so no need for checking
FinalResult.Add(a[i]);
}
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How to break two for loop at the highlighted line. (after showing the MessageBox.Show("THE ITEM ID DOES NOT EXIST.!"); )
bool conditionitem = true;
for (int cun = 0; cun < ItemIdNumber.Length; cun++)
{
int Item_Id = Convert.ToInt32(ItemIdNumber[cun]);
for (int yyu = 0; yyu <= 1258038; yyu++)
{
int weer = c[yyu];
if (weer == Item_Id)
{
conditionitem = false;
itemseq = yyu;
}
}
if (conditionitem != false)
{
MessageBox.Show("THE ITEM ID DOES NOT EXIST.!");
break; //--> here i want two break for two times
}
}
By this break it only break the first loop.
Two options I can think of:
(1) Set a flag inside the second loop before you break out of it. Follow the inner iteration with a condition that breaks out of the first iteration if the flag is set.
bool flag = false;
foreach (item in Items)
{
foreach (item2 in Items2)
{
flag = true; // whenever you want to break
break;
}
if (flag) break;
}
(2) Use a goto statement.
foreach (item in Items)
{
foreach (item2 in Items2)
{
goto GetMeOutOfHere: // when you want to break out of both
}
}
GetMeOutOfHere:
// do what you want to do.
You can refactor the loop to be a method that finds the item:
SomeType SomeMethod(int itemId)
{
for (int cun = 0; cun < ItemIdNumber.Length; cun++)
{
int Item_Id = Convert.ToInt32(ItemIdNumber[cun]);
for (int yyu = 0; yyu <= 1258038; yyu++)
{
if (c[yyu] == itemId) return yyu;
}
}
return null;
}
Then just use that:
var item = SomeMethod(Item_Id);
if(item == null)
{
MessageBox.Show("THE ITEM ID DOES NOT EXIST.!");
}
else
{
// ...
}
This also avoids mixing UI logic and internal logic.
Put your nested loop into a function and return true/false whenever you want to break the loop?
bool Function()
{
for(int i = 0; i < 10; ++i)
{
for(int j = 0; j < 10; ++j)
{
if (error)
{
MessageBox.Show("THE ITEM ID DOES NOT EXIST.!");
return false;
}
}
}
return true;
}
Now I have another problem with WCF server/client.
I have a method:
bool spr_wiersz(int wiersz, int kolumna) //check_row(int row, int column)
{
for (int i = 0; i < 9; i++)
{
if (i != kolumna)
{
//if(grid(row,i)==grid[row,column]
if (tablica[wiersz, i] == tablica[wiersz, kolumna])
return false;
}
}
return true;
}
And I want send every one value to clients and they will check it and return true, or false to server.
ex.
client 1 compare for i=0
client 2 compare for i=1
client 3 compare for i=2
client 1 compare for i=3
client 2 compare for i=4
......
To send something to everyone clients I use :
subscribers.ForEach(delegate(ImessageCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
}
});
I hevan't any idea how conect this ;/
And another problem is, how send grid to client to compare value.
I solve the problem :)
it almost work properly.
bool spr_wiersz(int wiersz, int kolumna)
{
wys_tab();
Console.WriteLine("wiersz: {0}, kolumna: {1}", wiersz, kolumna);
int i_wiersz=0;
bool[] result = new bool[9];
while (i_wiersz < 9)
{
subscribers.ForEach(delegate(ImessageCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
Console.WriteLine("wiersz: {0}, kolumna: {1}, i: {2}", wiersz, kolumna, i_wiersz);
result[i_wiersz] = callback.spr_wiersz(wiersz, kolumna, i_wiersz);
i_wiersz++;
}
});
for (int j = 0; j < i_wiersz; j++)
{
if (result[j] == false)
{
return false;
}
}
}
return true;
}
It's work good only for 1,3 or 9 clients. For other number of clients this doesn't work yet.