-1

I'm trying to modify this code. I need to check for a value in a specific element of FilteredCheckObservable and if true, change the value of another part of that element.

Basically something like

if (FilteredCheckObservable items.Lang = 'ENG')
    {items.check = newcheckname;}

Then this will update the sourceGroups Collection.

    if (string.IsNullOrEmpty(departmentLine.LineID) || string.IsNullOrEmpty(departmentLine.LineName))
        continue;
        
    bool discovered = false;
    foreach (var group in sourceGroups)
    {
         if (!group.Key.Line.IsEqual(departmentLine))
             continue;
         group.Key.IsDiscovered = true;
         discovered = true;
         group.Key.ScheduleStatusCount = group.CountGroupItem;
         break;
    }
    if (discovered == false)
    {
        var _ScheduleItemObservable = new ScheduleItemObservable(departmentLine, MainViewViewModel, Shift.ToString());
                    
        var item = new Grouping<ScheduleItemObservable, FilteredCheckObservable>(_ScheduleItemObservable);
        if (IsShiftValid)
        {
            item.Key.Shift = Shift.ToString();
            item.Key.IsHistoryEnabled = true;
        }
        sourceGroups.Add(item);                     
    }
for (int index = 0; index < sourceGroups.Count; index++)
                        {
                            if (sourceGroups[index].Key.IsDiscovered == true)
                            {
                                foreach (var group in sourceGroups)
                                {
                                    foreach (FilteredCheckObservable items in group)
                                    {
                                        if (items.Lang_ID == LanguageService.Instance.LanguageType.ToString())
                                        {
                                            sourceGroups.Clear();
                                            sourceGroups.Add(item);
                                        }
                                    }
                                }
                            }
                        }
Jason
  • 86,222
  • 15
  • 131
  • 146
Travis
  • 3
  • 5
  • 1
    Could you keep only the relevant code to the question please, in order to gain clarity, to someone who doesn't know your code it might be confusing to see bunch of code without knowing the context and link between. – Cfun Apr 22 '21 at 01:09
  • I apologize. The first snippet is the functional code that builds the collection via the sourceGroups.Add(). The 2nd snippet was my poor attempt to manipulate the collection. Thanks for your help. – Travis Apr 22 '21 at 01:18
  • this is a general C# question, it has nothing specific to do with Xamarin – Jason Apr 22 '21 at 01:31

1 Answers1

0

Welcome Travis,

I would wager the guilty culprit is your foreach loop. https://stackoverflow.com/a/759985/3403999

You aren't allowed to modify a collection inside of a foreach loop. I don't know if your collection has an indexer, but if it does, you can convert to a for loop:

for (int i = 0; i < sourceGroups.Count; i++)
{
    var group = sourceGroups[i];
    // The rest of your code.

I could be wrong. You do say you are trying to modify some existing code. Is it some code that is online? Maybe you could link to it to provide a full context.

Based on your new snippet, you need two for loops:

for (int index = 0; index < sourceGroups.Count; index++)
{
    if (sourceGroups[index].Key.IsDiscovered == true)
    {
        //foreach (var group in sourceGroups)
    for (int j = 0; j < sourceGroups.Count; j++)
        {
            var group = sourceGroups[j];
            foreach (FilteredCheckObservable items in group)
            {
                if (items.Lang_ID == LanguageService.Instance.LanguageType.ToString())
                {
                    sourceGroups.Clear();
                    sourceGroups.Add(item);
                }
            }
        }
    }
}

^ Although that might still be a bad loop. Primarily because you have sourceGroups.Clear();.

What you might be better off doing is creating an internal collection called say 'results'. Do your loop looking for your conditions, and if they meet, add that item to the results collection.

Once your loops terminate, then call sourceGroups.Clear(), and then sourceGroups.AddRange(results). If sourceGroups doesn't have an AddRange, then one final loop of:

foreach (var group in results) { sourceGroups.Add(group); }
B.O.B.
  • 704
  • 4
  • 10
  • Thanks for the quick response. The code I quoted is working as it builds the initial collection. What I need to do is on a button event, go back to this collection and change part of the value. I actually have another piece of code where I was attempting this... I'll copy here: – Travis Apr 22 '21 at 00:58
  • I added a 2nd snippet of code of what I was attempting to do. – Travis Apr 22 '21 at 01:01
  • @Travis `sourceGroups.Clear(); sourceGroups.Add(item);` <- both of those lines are altering the collection from inside of the foreach group. Let me take your 2nd snippet and edit my answer.... – B.O.B. Apr 22 '21 at 01:11
  • So with your 'Clear()' call, at best when it gets all done, you should have only a single item in your collection that is the very last success match. Also, if you are indeed using an ObservableCollection, every time you call .Clear and .Add on it, it's going to fire events which is going to be an expensive process. Better to figure out what items you want to add in an internal collection, and then call 'AddRange'. This will let you add all the items and only fire a single event at the end. – B.O.B. Apr 22 '21 at 01:25
  • How do I build the internal results list? – Travis Apr 22 '21 at 01:47