Home > Blockchain >  Spliting a int array on a specific element
Spliting a int array on a specific element

Time:10-31

so I was solving some unrelated coding challenge and I needed to split an int array based on an element.

similar to how String.Split works.

for example:

var arr1 = new int [] { 3, 3, 0, 2, 4, 3, 2 };
var arr2 = new int [] { 8, 8, 5, 7, 9, 8, 7, 4, 8 };
var results1 = Split(arr1, 0);
foreach (var arr in results1)
    Console.WriteLine(string.Join(",", arr));
var results2 = Split(arr2, 8);
foreach (var arr in results2)
    Console.WriteLine(string.Join(",", arr));

the output here is:

3,3

2,4,3,2

5,7,9

7,4

I was surprised, I could not find any answers for this, String.Split kept coming up, but no integer!

so I wrote this:

public int[][] Split(int[] arr, int element)
{
    List<int[]> arrays = new List<int[]>();
    int skip = 0;
    int take = 0;
    for (int i = 0; i < arr.Length; i  )
    {
        if (arr[i] == element && take != 0)
        {
            arrays.Add(arr.Skip(skip).Take(take).ToArray());
            skip = i   1;
            take = 0;
            continue;
        }

        if (arr[i] != element)
            take  ;

        if (take == 0)
            skip = i   1;

        if (arr.Length - 1 == i && take != 0)
            arrays.Add(arr.Skip(skip).Take(take).ToArray());
     }

     return arrays.ToArray();
 }

this works (I think), but it is very messy and I don't like it

Any other solutions?

CodePudding user response:

In general case, you can implement it (String.Split like routine but for IEnumerable<T>) as follows:

public static IEnumerable<T[]> Split<T>(IEnumerable<T> source, 
                                        T delimiter, 
                                        StringSplitOptions options = StringSplitOptions.None,
                                        IEqualityComparer<T> comparer = null) {
  if (null == source)
    yield break; // Or throw new ArgumentNullException(nameof(source));

  if (null == comparer)
    comparer = EqualityComparer<T>.Default;
  
  List<T> current = new List<T>();

  foreach (T item in source) {
    if (comparer.Equals(item, delimiter)) {
      if (current.Count > 0 || !options.HasFlag(StringSplitOptions.RemoveEmptyEntries))
        yield return current.ToArray();

      current.Clear();
    }
    else
      current.Add(item);
  }

  if (current.Count > 0 || !options.HasFlag(StringSplitOptions.RemoveEmptyEntries))
    yield return current.ToArray();
}     

Then

var arr1 = new int [] { 3, 3, 0, 2, 4, 3, 2 };
var results1 = Split(arr1, 0);

foreach (var arr in results1)
  Console.WriteLine(string.Join(", ", arr));

CodePudding user response:

    public static IEnumerable<List<TValue>> SplitBy<TValue>(List<TValue> source, TValue by)
        {
            int start = 0;
            int count = 0;
            foreach (TValue item in source)
            {
                if (item.Equals(by))
                {
                    List<TValue> part = source.GetRange(start, count);
                    start = start   count   1;
                    count = 0;
                    if (part.Any())
                    {
                        yield return part;
                    }
                }
                else
                {
                    count  ;
                }
                
            }
            
            List<TValue> rest = source.GetRange(start, count);
            yield return rest;
        }

https://dotnetfiddle.net/Widget/Preview?url=/Widget/7ORu8p

  • Related