60

I'm working on a simple blackjack game project. Firstly I create the array of cards:

string[] deck = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", };

than I multiply it 4 and given deckNumber:

newDeck = Enumerable.Repeat(deck, deckNumber*4).SelectMany(x => x).ToArray();

when I want to delete last card from array I apply this:

newDeck = newDeck.Where(w => w != newDeck.Last()).ToArray();

so the problem is that code doesn't removes last item from array, acts like there are multiple arrays and removes all last elements from them. For example with one deck:

cards: 2 3 4 5 6 7 8 9 10 J Q K A 2 3 4 5 6 7 8 9 10 J Q K A 2 3 4 5 6 7 8 9 10 J Q K A 2 3 4 5 6 7 8 9 10 J Q K A 

when I apply my remove command it become:

cards: 2 3 4 5 6 7 8 9 10 J Q K 2 3 4 5 6 7 8 9 10 J Q K 2 3 4 5 6 7 8 9 10 J Q K 2 3 4 5 6 7 8 9 10 J Q K 

it removes all the A's from array. But I want to remove only the last item from whole array. Whats the problem how can I solve this?

aloisdg
  • 22,270
  • 6
  • 85
  • 105
JayGatsby
  • 1,541
  • 6
  • 21
  • 41

4 Answers4

105

To remove just the last element use this:

newDeck = newDeck.Take(newDeck.Count() - 1).ToArray();

Your solution removes all Elements that are equal to the last element. For a string, this means, it removes all elements equal to A

Flat Eric
  • 7,971
  • 9
  • 36
  • 45
46

You can use Array class to resize:

Array.Resize(ref result, result.Length - 1);

It creates a new array with a specified size and copies elements to the new array. It does not actually resize the array, naming is a bit misleading.

It is actually not possible to resize an array. Arrays are fixed collections. It is by design to keep implementations of array efficient.

Ahmet Arslan
  • 5,380
  • 2
  • 33
  • 35
  • 7
    I just tried this method versus Flat Eric's method (`.Take`) and this method (`.Resize`) is consistently faster. And I mean consistently, like I would bet a huge amount of money. The longer the array, the greater the difference. – Andrew Steitz May 15 '19 at 21:15
  • Agreed. The speed boost is nice, too. ;-) – Andrew Steitz May 22 '19 at 19:48
11

@Flat Eric explained why your solution is not working.

Here is alternate for removing last element:

newDeck = newDeck.Reverse().Skip(1).Reverse().ToArray();

Clarification:

[a, b, c] => Reverse => [c, b, a] => Skip(1) => [b, a] => Reverse() => [a, b]
11

It's easy to remove the last item of an array if you're using C# 8.0 (released with .net 3.0) or above.

You can remove the last item by combining the "hat" ^ operator with the range .. operator:

newDeck = newDeck[..^1];  // all items in the array except the last

Some other examples of ^ and ..:

var lastItem   = newDeck[^1];    // last item in array
var allItems   = newDeck[..];    // all items
var skipTwo    = newDeck[2..];   // all items except the first 2 items
var innerItems = newDeck[1..^1]  // all items except the first and last

Online demo

haldo
  • 14,512
  • 5
  • 46
  • 52