Oleksandr Novik
Oleksandr Novik

Reputation: 738

How to create a custom foreach loop?

I'm trying to understand how to use IEnumerable and IEnumerator interfaces at the moment. To tell the story short, I need to create a custom foreach loop that will replace each "1" element with "0". Here's the code that still doesn't replace any element and still prints the same values:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour, IEnumerator, IEnumerable
{
   private IEnumerator _enumerator;

   private readonly List<int> _nums = new List<int>{1, 2 ,4};
   private int _position = -1;

   public IEnumerator GetEnumerator()
   {
      return _nums.GetEnumerator();
   }

   public bool MoveNext()
   {
      if (_position < _nums.Count - 1)
      {
         _position++;
         return false;
      }
      return true;
   }

   public void Reset()
   {
      _position = -1;
   }

   public object Current
   {
      get {
         if (_nums[_position] == 1)
         {
            return 0; 
         }
         return _nums[_position];
      }
   }

   private void Start()
   {
      foreach (var i in _nums)
      {
         Debug.Log(_nums[i]);
      }
   }
}

I'll appreciate any help :P

Upvotes: 0

Views: 928

Answers (1)

Sean
Sean

Reputation: 62492

It looks like what you're trying to do is just iterate over a sequence, replacing 1 with 0. In that case it'll be easier to wrap this in a method that does a yield return:

IEnumerable<int> GetValues(IEnumerale<int> source)
{
  foreach(var value in source)
  {
    if(value == 1)
    {
      yield return 0;
    }
    else
    {
      yield return value;
    }
  }
}

Now if you've got:

List<int> _nums = new List<int>{1, 2 ,4};

Then you can say:

foreach(var value in GetValues(_nums))
{
  Console.WriteLine(value);
}

You can also do this with Linq using the Select method:

foreach(var value in _nums.Select(v => v == 1 ? 0 : v))
{
  Console.WriteLine(value);
}

Upvotes: 4

Related Questions