Use System.Collections.ObjectModel.Collection<Foo>.
abatishchev
1
Para o meu jogo, fui com uma estrutura de dados "null at index". Basicamente, a matriz interna (buffer) é de tamanho estático e, em vez de remover o índice e redimensionar a matriz, apenas anulo o índice. Quando preciso adicionar um item, localizo o primeiro índice não nulo e o coloco lá. Funciona muito bem, mas obviamente não para tudo.
Krythic 17/09/16
Respostas:
202
Se você não quiser usar a Lista:
var foos =newList<Foo>(array);
foos.RemoveAt(index);return foos.ToArray();
Você pode tentar este método de extensão que eu realmente não testei:
publicstatic T[]RemoveAt<T>(this T[] source,int index){
T[] dest =new T[source.Length-1];if( index >0)Array.Copy(source,0, dest,0, index);if( index < source.Length-1)Array.Copy(source, index +1, dest, index, source.Length- index -1);return dest;}
O primeiro exemplo dado nesta resposta é muito menos eficiente que o segundo. Requer duas cópias de matriz e uma troca de tudo após o índice, em vez de uma cópia de matriz seletiva.
Martin Brown
2
+1, é claro, mas também podemos usar a lista OU OU List <Foo> list = new List <Foll> (GetFoos ()); list.Remove (my_foo); list.RemoveAt (2); onde GetFoos () retornará a matriz de Foos !!!!
21009 shahjapan
2
A primeira linha dentro do método deve dizer 'source.Length' em vez de 'array.Length'.
Nelson
1
Além disso, lembre-se de que qualquer variável que armazene uma referência à matriz original continuará a conter os dados originais e que qualquer comparação de igualdade de referência entre a matriz na origem e a matriz de saída retornará um valor negativo.
bkqc
1
@MartinBrown Na verdade, a conversão de uma lista para \ e array é muito mais lenta que uma cópia de array (que é capaz de copiar os dados na velocidade máxima permitida pela CPU com apenas algumas instruções ASM). Além disso, mudar uma lista é muito rápido, porque é apenas uma questão de trocar alguns ponteiros e remover os dados do nó (neste caso, são apenas 8 bytes [mais outros 16 para os ponteiros head \ tail]).
precisa saber é o seguinte
66
A natureza das matrizes é que seu comprimento é imutável. Você não pode adicionar ou excluir nenhum dos itens da matriz.
Você precisará criar uma nova matriz com um elemento mais curto e copiar os itens antigos para a nova matriz, excluindo o elemento que deseja excluir.
Portanto, provavelmente é melhor usar uma lista em vez de uma matriz.
Converta a matriz em uma listaList<mydatatype> array = new List<mydatatype>(arrayofmydatatype)
Immortal Blue
1
@ImmortalBlue ou apenas var myList = myArray.ToList();usando o Enumerable.ToList()método no System.Linqespaço para nome.
Dyndrilliac
58
Eu uso esse método para remover um elemento de uma matriz de objetos. Na minha situação, minhas matrizes são pequenas. Portanto, se você tiver matrizes grandes, poderá precisar de outra solução.
Pessoalmente, gosto mais desta resposta do que da resposta aceita. Deve ser igualmente eficiente e muito mais fácil de ler. Eu posso olhar e saber que está correto. Eu teria que testar o outro para garantir que essas cópias foram escritas corretamente.
Oillio 8/03
1
É realmente uma pena que essa resposta seja tão baixa, quando é de longe melhor do que as duas acima.
Sepulchritude
Aaarhg, essa é a resposta que eu estava procurando! Este é o melhor método sem listas.
Jordi Huertas
47
Solução de linha única LINQ:
myArray = myArray.Where((source, index)=> index !=1).ToArray();
O 1exemplo nesse exemplo é o índice do elemento a ser removido - neste exemplo, pela pergunta original, o 2º elemento ( 1sendo o segundo elemento na indexação de matriz baseada em zero em C #).
Para áreas que exigem acesso frequente / de alto desempenho, o LINQ não é recomendado.
Krythic 17/09/16
3
@ Krythic Esse é um comentário justo. Executar milhares de vezes em um loop apertado, o desempenho deste solução não é tão tão bom quanto algumas das outras soluções altamente votada esta página: dotnetfiddle.net/z9Xkpn
Jon Schneider
9
Esta é uma maneira de excluir um elemento da matriz, a partir do .Net 3.5, sem copiar para outra matriz - usando a mesma instância da matriz com Array.Resize<T>:
publicstaticvoidRemoveAt<T>(ref T[] arr,int index){for(int a = index; a < arr.Length-1; a++){// moving elements downwards, to fill the gap at [index]
arr[a]= arr[a +1];}// finally, let's decrement Array's size by oneArray.Resize(ref arr, arr.Length-1);}
"sem copiar para outro array" - acordo com a documentação vinculada, Array.Resize realmente faz alocar uma nova matriz nos bastidores, e copia os elementos da antiga matriz para o novo. Ainda assim, gosto da concisão dessa solução.
9119 Jon Schneider
Muito bonito e claro, se você tem certeza de que é uma matriz relativamente pequena.
Darren
1
Continuando o comentário de @ JonSchneider, não é "a mesma instância de matriz". É por isso que você precisa usar refquando chama o Resizemétodo. O comprimento de uma instância de matriz é fixo e imutável.
Jeppe Stig Nielsen
2
Se a ordem dos elementos não for importante, em vez de mover todos os elementos para baixo, você poderá trocar o elemento no índice pelo último elemento e redimensionar: arr [index] = arr [arr.Length - 1]; Array.Resize (ref arr, arr.Length - 1);
Bartel
5
Aqui está uma versão antiga que funciona na versão 1.0 do .NET framework e não precisa de tipos genéricos.
publicstaticArrayRemoveAt(Array source,int index){if(source ==null)thrownewArgumentNullException("source");if(0> index || index >= source.Length)thrownewArgumentOutOfRangeException("index", index,"index is outside the bounds of source array");Array dest =Array.CreateInstance(source.GetType().GetElementType(), source.Length-1);Array.Copy(source,0, dest,0, index);Array.Copy(source, index +1, dest, index, source.Length- index -1);return dest;}
Isso é usado assim:
classProgram{staticvoidMain(string[] args){string[] x =newstring[20];for(int i =0; i < x.Length; i++)
x[i]=(i+1).ToString();string[] y =(string[])MyArrayFunctions.RemoveAt(x,3);for(int i =0; i < y.Length; i++)Console.WriteLine(y[i]);}}
publicstaticElementDefinitionImpl[]RemoveElementDefAt(ElementDefinition[] oldList,int removeIndex
){ElementDefinitionImpl[] newElementDefList =newElementDefinitionImpl[ oldList.Length-1];int offset =0;for(int index =0; index < oldList.Length; index++){ElementDefinitionImpl elementDef = oldList[ index ]asElementDefinitionImpl;if( index == removeIndex ){// This is the one we want to remove, so we won't copy it. But // every subsequent elementDef will by shifted down by one.
offset =-1;}else{
newElementDefList[ index + offset ]= elementDef;}}return newElementDefList;}
Em uma matriz normal, você deve embaralhar todas as entradas da matriz acima de 2 e redimensioná-la usando o método Resize. Você pode estar melhor usando um ArrayList.
Aqui está uma pequena coleção de métodos auxiliares que produzi com base em algumas das respostas existentes. Ele utiliza extensões e métodos estáticos com parâmetros de referência para máxima idealidade:
publicstaticclassArr{publicstaticintIndexOf<TElement>(thisTElement[]Source,TElementElement){for(var i =0; i <Source.Length; i++){if(Source[i].Equals(Element))return i;}return-1;}publicstaticTElement[]Add<TElement>(refTElement[]Source,paramsTElement[]Elements){varOldLength=Source.Length;Array.Resize(refSource,OldLength+Elements.Length);for(int j =0,Count=Elements.Length; j <Count; j++)Source[OldLength+ j]=Elements[j];returnSource;}publicstaticTElement[]New<TElement>(paramsTElement[]Elements){returnElements??newTElement[0];}publicstaticvoidRemove<TElement>(refTElement[]Source,paramsTElement[]Elements){foreach(var i inElements)RemoveAt(refSource,Source.IndexOf(i));}publicstaticvoidRemoveAt<TElement>(refTElement[]Source,intIndex){varResult=newTElement[Source.Length-1];if(Index>0)Array.Copy(Source,0,Result,0,Index);if(Index<Source.Length-1)Array.Copy(Source,Index+1,Result,Index,Source.Length-Index-1);Source=Result;}}
Em termos de desempenho, é decente, mas provavelmente poderia ser melhorado. Removedepende IndexOfe uma nova matriz é criada para cada elemento que você deseja remover chamando RemoveAt.
IndexOfé o único método de extensão, pois não precisa retornar a matriz original. Newaceita vários elementos de algum tipo para produzir uma nova matriz do referido tipo. Todos os outros métodos devem aceitar a matriz original como referência, para que não seja necessário atribuir o resultado posteriormente, pois isso já ocorre internamente.
Eu teria definido um Mergemétodo para mesclar duas matrizes; no entanto, isso já pode ser realizado com o Addmétodo passando uma matriz real versus vários elementos individuais. Portanto, Addpode ser usado das duas maneiras a seguir para unir dois conjuntos de elementos:
Eu sei que este artigo tem dez anos e, portanto, provavelmente está morto, mas eis o que eu tentaria fazer:
Use o método IEnumerable.Skip (), encontrado em System.Linq . Ele pulará o elemento selecionado da matriz e retornará outra cópia da matriz que contém apenas tudo, exceto o objeto selecionado. Em seguida, basta repetir isso para cada elemento que você deseja remover e depois salvá-lo em uma variável.
Por exemplo, se tivermos uma matriz denominada "Amostra" (do tipo int []) com 5 números. Queremos remover o segundo, tentando "Sample.Skip (2);" deve retornar a mesma matriz, exceto sem o segundo número.
Esse método não ignora apenas um número especificado de elementos em uma sequência e retorna os elementos restantes ? No seu exemplo, você "pulará" os dois primeiros elementos da lista genérica e não apenas o segundo!
Xnr_z 11/11/19
-4
Primeiro passo:
você precisa converter o array em uma lista, pode escrever um método de extensão como este
// Convert An array of string to a list of stringpublicstaticList<string>ConnvertArrayToList(thisstring[]array){// DECLARE a list of string and add all element of the array into itList<string> myList =newList<string>();foreach(string s inarray){
myList.Add(s);}return myList;}
Segundo passo
Escreva um método de extensão para converter novamente a lista em uma matriz
// convert a list of string to an array publicstaticstring[]ConvertListToArray(thisList<string>list){string[]array=newstring[list.Capacity];array=list.Select(i => i.ToString()).ToArray();returnarray;}
Últimos passos
Escreva seu método final, mas lembre-se de remover o elemento no índice antes de converter novamente em uma matriz como o código show
System.Collections.ObjectModel.Collection<Foo>
.Respostas:
Se você não quiser usar a Lista:
Você pode tentar este método de extensão que eu realmente não testei:
E use-o como:
fonte
A natureza das matrizes é que seu comprimento é imutável. Você não pode adicionar ou excluir nenhum dos itens da matriz.
Você precisará criar uma nova matriz com um elemento mais curto e copiar os itens antigos para a nova matriz, excluindo o elemento que deseja excluir.
Portanto, provavelmente é melhor usar uma lista em vez de uma matriz.
fonte
List<mydatatype> array = new List<mydatatype>(arrayofmydatatype)
var myList = myArray.ToList();
usando oEnumerable.ToList()
método noSystem.Linq
espaço para nome.Eu uso esse método para remover um elemento de uma matriz de objetos. Na minha situação, minhas matrizes são pequenas. Portanto, se você tiver matrizes grandes, poderá precisar de outra solução.
fonte
Solução de linha única LINQ:
O
1
exemplo nesse exemplo é o índice do elemento a ser removido - neste exemplo, pela pergunta original, o 2º elemento (1
sendo o segundo elemento na indexação de matriz baseada em zero em C #).Um exemplo mais completo:
Depois de executar esse snippet, o valor de
myArray
será{ "a", "c", "d", "e" }
.fonte
Esta é uma maneira de excluir um elemento da matriz, a partir do .Net 3.5, sem copiar para outra matriz - usando a mesma instância da matriz com
Array.Resize<T>
:fonte
ref
quando chama oResize
método. O comprimento de uma instância de matriz é fixo e imutável.Aqui está uma versão antiga que funciona na versão 1.0 do .NET framework e não precisa de tipos genéricos.
Isso é usado assim:
fonte
Não é exatamente o caminho a seguir, mas se a situação for trivial e você valorizar seu tempo, tente isso para tipos anuláveis.
e depois verifique se há entradas nulas na sua lógica.
fonte
Como sempre, estou atrasado para a festa ...
Eu gostaria de adicionar outra opção à boa lista de soluções já presente. =)
Eu consideraria isso uma boa oportunidade para extensões.
Referência: http://msdn.microsoft.com/en-us/library/bb311042.aspx
Então, definimos alguma classe estática e nela, nosso método.
Depois disso, podemos usar nosso método estendido, quer ou não. =)
fonte
Experimente o código abaixo:
ou
fonte
Aqui está como eu fiz isso ...
fonte
Em uma matriz normal, você deve embaralhar todas as entradas da matriz acima de 2 e redimensioná-la usando o método Resize. Você pode estar melhor usando um ArrayList.
fonte
fonte
Aqui está uma pequena coleção de métodos auxiliares que produzi com base em algumas das respostas existentes. Ele utiliza extensões e métodos estáticos com parâmetros de referência para máxima idealidade:
Em termos de desempenho, é decente, mas provavelmente poderia ser melhorado.
Remove
dependeIndexOf
e uma nova matriz é criada para cada elemento que você deseja remover chamandoRemoveAt
.IndexOf
é o único método de extensão, pois não precisa retornar a matriz original.New
aceita vários elementos de algum tipo para produzir uma nova matriz do referido tipo. Todos os outros métodos devem aceitar a matriz original como referência, para que não seja necessário atribuir o resultado posteriormente, pois isso já ocorre internamente.Eu teria definido um
Merge
método para mesclar duas matrizes; no entanto, isso já pode ser realizado com oAdd
método passando uma matriz real versus vários elementos individuais. Portanto,Add
pode ser usado das duas maneiras a seguir para unir dois conjuntos de elementos:Ou
fonte
Eu sei que este artigo tem dez anos e, portanto, provavelmente está morto, mas eis o que eu tentaria fazer:
Use o método IEnumerable.Skip (), encontrado em System.Linq . Ele pulará o elemento selecionado da matriz e retornará outra cópia da matriz que contém apenas tudo, exceto o objeto selecionado. Em seguida, basta repetir isso para cada elemento que você deseja remover e depois salvá-lo em uma variável.
Por exemplo, se tivermos uma matriz denominada "Amostra" (do tipo int []) com 5 números. Queremos remover o segundo, tentando "Sample.Skip (2);" deve retornar a mesma matriz, exceto sem o segundo número.
fonte
Primeiro passo:
você precisa converter o array em uma lista, pode escrever um método de extensão como este
Segundo passo
Escreva um método de extensão para converter novamente a lista em uma matriz
Últimos passos
Escreva seu método final, mas lembre-se de remover o elemento no índice antes de converter novamente em uma matriz como o código show
exemplos de códigos podem ser encontrados no meu blog , acompanhe.
fonte
.ToArray()
e umList<T>
construtor que leva uma seqüência existente ...