23

There is a List<int> containing some set of numbers. Randomly I select an index, which will be processed separately (call it master). Now, I want to exclude this particular index, and get all other elements of List (call them slave).

var items = new List<int> { 55, 66, 77, 88, 99 };
int MasterIndex = new Random().Next(0, items .Count);

var master = items.Skip(MasterIndex).First();

// How to get the other items into another List<int> now? 
/*  -- items.Join;
    -- items.Select;
    -- items.Except */

Join, Select, Except - any of them, and how?

EDIT: Cannot remove any item from the original list, otherwise I have to keep two lists.

Ajay
  • 18,086
  • 12
  • 59
  • 105
  • 2
    I know that this is an old question, but it may be worth considering replacing the terms "master" and "slave" - the tech industry in general is moving away from these terms due to their association with slavery. Some suggested alternatives: https://en.wikipedia.org/wiki/Master/slave_(technology)#Possible_replacement_conventions – Lou Aug 13 '21 at 07:42
  • Fair point @Lou – Ajay Aug 16 '21 at 15:57

3 Answers3

43

Use Where:-

var result = numbers.Where((v, i) => i != MasterIndex).ToList();

Working Fiddle.

Rahul Singh
  • 21,585
  • 6
  • 41
  • 56
  • Lovely! It works flawlessly. This form of `Where` wasn't obvious anywhere in documentation. – Ajay Dec 31 '14 at 10:14
  • @Ajay - Documentation is there, check the link I have shared for `Where`, its the second overload of Where. – Rahul Singh Dec 31 '14 at 10:15
  • 2
    Yeah. By this time, I have already utilized this approach in the actual product code (which isn't obviously list of ints). – Ajay Dec 31 '14 at 10:16
4

If performance is an issue you may prefer to use the List.CopyTo method like this.

List<T> RemoveOneItem1<T>(List<T> list, int index)
{
    var listCount = list.Count;

    // Create an array to store the data.
    var result = new T[listCount - 1];

    // Copy element before the index.
    list.CopyTo(0, result, 0, index);

    // Copy element after the index.
    list.CopyTo(index + 1, result, index, listCount - 1 - index);

    return new List<T>(result);
}

This implementation is almost 3 times faster than @RahulSingh answer.

Orace
  • 7,822
  • 30
  • 45
3

You could remove Master item from the list,

List<int> newList = items.RemoveAt(MasterIndex);

RemoveAt() removes the item from the original list, So it's not necessary to assign the collection to a new list. After calling RemoveAt(), items.Contains(MasterItem) would return false.

Kurubaran
  • 8,696
  • 5
  • 43
  • 65
  • Requires two lists. I need to keep original! – Ajay Dec 31 '14 at 09:58
  • 1
    @Ajay RemoveAt() removes the item from the original list, So it's not necessary to assign it to a new list. After calling RemoveAt() "items" will not have master item in it. – Kurubaran Dec 31 '14 at 10:00
  • 1
    So, you want I should read from DB, network, file again? That is not appropriate. – Ajay Dec 31 '14 at 10:04
  • @Ajay Just saw your edit that you dont want to remove item from original list. – Kurubaran Dec 31 '14 at 10:06