1

How to split a byte array by a particular array value in c#?

    byte[] largeBytes = [70,68,49,59,117,49,59,112]; 

I just want to split the array bye "59" so that I can get 3 byte arrays. I have tried a lot ,couldn't find the solution. thanks in advance

Abdu
  • 185
  • 1
  • 7
  • 17

4 Answers4

1

The easiest solution is to use the Split extension method from MoreLINQ :

byte separator=59;
var triplets=largeBytes.Split(separator);

This will return an IEnumerable of IEnumerable<byte>. You can convert it to an IEnumerable<byte[]> with ToArray():

var triplets=largeBytes.Split(separator).Select(triplet=>triplet.ToArray());

Or you can do roughly what the extension method does - create an iterator that checks each input element until it finds the separator and places each character in an array:

public static IEnumerable<List<T>> Split<T>(this IEnumerable<T> source, T separator)
{
    List<T> result=new List<T>(3);
    foreach(T item in source)
    {
        if (item == separator)
        {
            yield return result;
            result=new List<T>(3);
        }
        else 
        {
            result.Add(item);
        }
    }
    yield return result;
}

You can use this extension method in the same way:

byte separator=59;
var triplets=largeBytes.Split(separator);

or

var triplets=MyExtensionsClass.Split(largeBytes,separator);

MoreLINQ's version is a lot more versatile, as it allows you to specify a maximum number of splits, or transform the input into another form

If you want to include the separator, you put result.Add before the first if. A better option would be to add an include parameter:

public static IEnumerable<List<T>> Split<T>(this IEnumerable<T> source, T separator,bool include=false)
{
    List<T> result=new List<T>(3);
    foreach(T item in source)
    {
        if (item == separator)
        {
            if (include) result.Add(item);
            yield return result;
            result=new List<T>(3);
        }
        else 
        {
            result.Add(item);
        }
    }
    yield return result;
}
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
0

You can use Array.IndexOf(largeBytes, (byte)59, index) where index will be last found index (0 in beginning) in loop, until function returns -1 (no more 59 found in array). On boundaries created by (byte)59, copy some sub-array as is written in this answer: Getting a sub-array from an existing array

Mike S.
  • 1,995
  • 13
  • 25
0

here is the algorithm on how you can achieve this

 //Here I'm not including 59 in the sub arrays  
       var largeBytes = new byte[] {70,68,49,59,117,49,59,112};
        var lists = new List<List<byte>>();
        const int marker = 59;
        var tempLst = new List<byte>();
        foreach (var largeByte in largeBytes)
        {


            if (largeByte==marker)
            {
                lists.Add(tempLst);               
                tempLst=new List<byte>();
            }
            else
            {
                tempLst.Add(largeByte);    
            }

        }
        lists.Add(tempLst);
BRAHIM Kamel
  • 13,492
  • 1
  • 36
  • 47
0

You could use IEnumerable's GroupBy to perform the split:

byte[] largeBytes = new byte[] {70,68,49,59,117,49,59,112};
byte split = 59;
long index = 0;
var results = largeBytes.GroupBy(b => index += Convert.ToInt64(b==split)); 
foreach (var result in results) {
    Console.WriteLine($"Group Key: {result.Key}");
    foreach (var value in result) {
        Console.WriteLine($" - Value: {value}");
    }
}

Just for fun, here's a way to do it using C#7's Tuples:

byte[] largeBytes = new byte[] {70,68,49,59,117,49,59,112};
byte split = 59;
long index = 0;
var results = largeBytes.Select(x => ((index += Convert.ToInt64(x == 59)),x));
foreach (var tuple in results) { 
    Console.WriteLine($"{tuple.Item1}: {tuple.Item2}");
}

Demo: http://csharppad.com/gist/079cc46095bb938f716587693d7ea8af

JohnLBevan
  • 22,735
  • 13
  • 96
  • 178