2015-06-23 2 views
3

Я совершенно новый в использовании List в качестве массивов в C#. Поэтому я сталкиваюсь с проблемой при ее использовании.Как удалить int [] из списка <int[]>?

Я пытаюсь удалить с int[] (целочисленным массивом) из List<int[]> с помощью Remove, но не удалило int[] из List<int[]>.

вот код:

List<int[]> trash = new List<int[]>() 
{ 
    new int[] {0,1}, 
    new int[] {1,0}, 
    new int[] {1,1} 
}; 
int[] t1 = {0,1}; 
trash.Remove(t1); 

Является ли это просто ошибка? Или он не признает int[]?

+1

это разные объекты. Вы должны удалить по индексу или с той же ссылкой – Andrea

+0

Не ошибка. Вы пытаетесь удалить массив, которого нет в списке. Ваша вторая попытка 'Console.WriteLine (t1 == trash [0])'. Они не то же самое. – Aron

+1

О, спасибо большое за ВСЕ ВАС. : D –

ответ

5

Проблема заключается в том, что каждый тип массива является ссылочным типом, а List удаляет элементы на основе равенства, где равенство для ссылочных типов по умолчанию является ссылочным равенством. Это означает, что вам нужно удалить тот же массив, что и в списке.

Ниже, например, работает отлично:

int[] t1 = {0,1}; 
List<int[]> trash = new List<int[]>() 
{ 
      t1, 
      new int[] {1,0}, 
      new int[] {1,1} 
}; 
trash.Remove(t1); 
+0

Вы хотите удалить * тот же самый массив? Вы должны использовать ссылки на массив, который хотите удалить, а не воссоздать новый массив с тем же содержимым, как показано в примере кода. Альтернативно, вы можете использовать на основе индекса RemoveAt – Georg

+0

, что произойдет, если есть 2 int [] с тем же значением, но первое из них было вне списка , как то, что вы сделали в приведенном выше ответе? –

+0

@GenesisMallari Значения не важны, только ссылки. Вы действительно хотите использовать 'int []'? Не будет ли подходящий тип (структура, возможно) лучше подходит? Затем вы можете реализовать равенство ценности так, как хотите. Или используйте другую коллекцию - если есть очевидный индекс, используйте словарь. Если вы только заботитесь о порядке, используйте стек. – Luaan

0

Ваша переменная t1 представляет собой новый экземпляр массива. Поэтому он не будет равен первому элементу в списке.

Try:

trash.Remove(trash[0]); 

или

trash.RemoveAt(0); 
+0

В этом случае последний вариант намного лучше, поскольку список не нуждается в поиске массива. – Georg

0

Метод .Remove выглядит адрес элемента. Если они равны, то они удаляются. Вы должны сделать так.

int[] t1 = {0,1}; 
int[] t2 =new int[] {1,0}; 
int[] t3 =new int[] {1,1}; 
List<int[]> trash = new List<int[]>() 
{ 
    t1,t2,t3  
}; 

trash.Remove(t1); 
0
foreach(var x in trash) 
{ 
    if(x[0] == t1[0] && x[1] == t[1]) 
    { 
     trash.Remove(x); 
     break; 
    } 
} 

это должно работать Aswell

+0

Он работает, но есть O (n²). Вы можете улучшить это, выполнив поиск по индексу в O (n). – Georg

+0

Я думаю, что это O (n * m), где n - размер списка, а m - размер массива – Andrea

+0

Я считал размер массива постоянным, но если вы хотите его взять, то это, конечно, O (n * m) против O (n² * m) – Georg

4

Если вы хотите удалить все списки, которые имеют такое же содержание (в том же порядке) в качестве целевого списка, вы можете сделать это, используя List.RemoveAll() вместе с Linq-х SequenceEqual():

List<int[]> trash = new List<int[]> 
{ 
    new [] {0, 1}, 
    new [] {1, 0}, 
    new [] {1, 1} 
}; 

int[] t1 = {0, 1}; 

trash.RemoveAll(element => element.SequenceEqual(t1)); 

Console.WriteLine(trash.Count); // Prints 2 

Это очень медленно, хотя. Лучше использовать индекс, если сможете.

2

Ошибка. Список массивов использует данные ссылочного типа. поэтому, пожалуйста, используйте метод RemoveAt из списка, как показано ниже:

List<int[]> trash = new List<int[]>() 
{ 
    new int[] {0,1}, 
    new int[] {1,0}, 
    new int[] {1,1} 
}; 
trash.RemoveAt(0); 

С RemoveAt вам нужно передать индекс массива целых чисел, который вы хотите удалить из списка.

0

Это просто потому, что вы пытаетесь удалить элемент, который является новым.

Его адресная ссылка отличается от объекта, который уже находится в списке. Именно поэтому он не удаляется.

Int - тип значения .. И Int [] является ссылочным типом ..

Так что, когда вы делаете это со списком Int

List<int> trash = new List<int>(){ 1, 13, 5 }; 
int t1 = 13; 
trash.Remove(t1);//it will removed 

Но для Int []

List<int[]> trash = new List<int[]>() 
{ 
    new int[] {0,1}, 
    new int[] {1,0}, 
    new int[] {1,1} 
}; 
var t1 = {0,1}; 
trash.Remove(t1);//t1 will not removed because "t1" address reference is different than the "new int[] {0,1}" item that is in list. 

Для remove-

trash.Remove(trash.Find(a => a.SequenceEqual(t1))); 

SequenceEqual() Определяет, будут ли две последовательности равны, сравнивая элементы, используя стандартное равенство com parer для их типа.

+0

ну, это дало мне тот же результат неудачи после добавления нового int [] перед значением. –

+0

Теперь вы можете увидеть мой ответ с описанием .. и с вашим решением. :) –

0

Если вы хотите удалить точную последовательность, но у вас нет возможности удалить точный объект (последовательность выходит из другого места), вы можете найти правильную последовательность, используя выражение лямбда или анонимный метод:

List<int[]> trash = new List<int[]> 
    { 
     new [] {0, 1}, 
     new [] {1, 0}, 
     new [] {1, 1} 
    }; 

int[] t1 = { 0, 1 }; 

//using anonymous method 
trash.RemoveAll(delegate(int[] element) { return element.SequenceEqual(t1); }); 

//using lambda expression 
trash.RemoveAll(element => element.SequenceEqual(t1)); 
Смежные вопросы