Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cropping the first element in a string array without copying all the elements to a new array

Tags:

arrays

c#

.net

Have a string array

string[] lines

I would like to remove the first element. So if the array has 5 elements, I want to end up with 4.

There is a number of ways to achieve this:

  1. Create a new string array, with the same size as the original minus one. Then simply copy all elements (except the first one). I don't like this because, well, you have to make whole new array and seemingly duplicate the memory usage (?)

  2. Use a collection like List that implements methods for this. But then it would be the same story: I would have to convert my string array to a list, then remove the first element, then convert the list to a string array (because I need a string array, not a list).

  3. System.Array.Resize() seems to be capable of "cropping" arrays, which is precisely what I need. However, it crops the "rightmost" elements, whereas I need to crop the first (leftmost) element instead.


My question is: is there a simpler way to eliminate the first element in a string array, ending up with an array whose size is one less than the original's?

like image 619
Voldemort Avatar asked Jan 09 '23 11:01

Voldemort


2 Answers

I don't know what you want to use the "cropped" version for, but a very cheap thing to do is top wrap lines in an ArraySegment<>, like this:

  var cropped = new ArraySegment<string>(lines, 1, 4);

Since .NET 4.5 (from 2012), ArraySegment<> implements some interfaces, so you can do things like:

  foreach (var l in cropped)
  {
      // ...
  }

(uses an explicit interface implementation on ArraySegment<>, the iteration variable l is strongly typed).

Remember that this is just a wrapper around the original array instance. If that array is modified, this is reflected in the ArraySegment<>. There was no copying (not even a shallow one).


If you need indexing and so on, box the value of your ArraySegment<> struct to either IReadOnlyList<> or IList<>:

  IReadOnlyList<string> croppedB = new ArraySegment<string>(lines, 1, 4);

or:

  IList<string> croppedC = new ArraySegment<string>(lines, 1, 4);
like image 78
Jeppe Stig Nielsen Avatar answered Feb 01 '23 02:02

Jeppe Stig Nielsen


If you are really into this whole "don't create a new array" you could use a startIndex and length variables and always have your whole array as it was and only mark a part of it as usable via those two values. But if you aren't into large array sizes and on-the-edge performance, your program will look a lot cleaner, will be easier to understand, create and maintain if you just create a new array:

var arrayMinusFirstElement = lines.Skip(1).ToArray()
like image 39
nvoigt Avatar answered Feb 01 '23 04:02

nvoigt