72

I have a string array like this.

string[] queries with data more than one string.

I want to skip the last string from the element and take the remaining. I have come up with

var remStrings = queries.Reverse().Skip(1).Take(queries.Length - 1);

Is there a better alternative to this?

dotcoder
  • 2,748
  • 9
  • 31
  • 50
  • Possible duplicate of [How to take all but the last element in a sequence using LINQ?](https://stackoverflow.com/questions/1779129/how-to-take-all-but-the-last-element-in-a-sequence-using-linq) – Andre Figueiredo Jul 04 '17 at 17:29

6 Answers6

118
var remStrings = queries.Take(queries.Length - 1);

No need to Reverse and Skip. Just take one less element than there are in the array.

If you really wanted the elements in the reverse order, you could tack on a .Reverse() to the end.

Justin Niessner
  • 236,029
  • 38
  • 403
  • 530
22

For anyone finding this now...

With the upcoming support for ranges and indices C# 8 and .NET Core 3.0 you can simply write

var remStrings = queries[..^1]

This is short for

var remStrings = queries[0..^1]

This works by converting the 0 and 1 to indices (System.Index), with the ^ being the marker (actually an operator) to index from the end of a sequence. From these indices a range (System.Range) is then generates which can then be used to access the array. (See https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#indices-and-ranges)

Currently this only works in the preview version of .NET Core 3.0

user1781290
  • 2,439
  • 20
  • 26
13

Microsoft's Reactive Extensions' Team has the Interactive Extensions (NuGet "System.Interactive") that lets you do this:

var remStrings = queries.SkipLast(1);
Enigmativity
  • 105,241
  • 11
  • 83
  • 163
12

Why not just have:

var remStrings = queries.Take(queries.Length-1);

Which will return them in the same order.

Append .Reverse() to swap the order if that's a necessary requirement:

var remStrings = queries.Take(queries.Length-1).Reverse();
ChrisF
  • 131,190
  • 30
  • 250
  • 321
3

This answer from a related post is also worth mentioning as it elegantly applies to any IEnumerable in a single pass, without the need to know its number of elements beforehand.

Community
  • 1
  • 1
Erwin Mayer
  • 17,112
  • 9
  • 82
  • 121
0

Edited: You could effectively replace your array with the same array minus the last element with the following line or code:

queries = queries.Take(queries.Length - 1).ToArray();

If you would like to create a method that does this for you, then you could use the following:

public static string[] TrimLastElement(string[] arr) {
    return arr.Take(arr.Length - 1).ToArray();
}

And implement it in your code like so:

queries = TrimLastElement(queries);
FrostyOnion
  • 536
  • 3
  • 9
  • There are no variables of type `var`. `var` is just a keyword that instructs the compiler to infer the type. Your line of code is identical to `var temp = temp.Take(temp.Length - 1).ToArray();`. – Enigmativity Jun 26 '17 at 04:36
  • I understand what you wanna say, it should be like `temp = temp.Take(temp.Length - 1).ToArray();` – ainasiart Sep 07 '17 at 18:47
  • Thank you for your feedback! My post has now been edited. – FrostyOnion Sep 29 '17 at 01:53