C # 'daki bir diziden bir öğe nasıl silinir


153

Diyelim ki bu diziye sahibim,

int[] numbers = {1, 3, 4, 9, 2};

Bir öğeyi "ad" ile nasıl silebilirim? 4 numara diyelim?

Silmeye bile ArrayListyardımcı olmadı mı?

string strNumbers = " 1, 3, 4, 9, 2";
ArrayList numbers = new ArrayList(strNumbers.Split(new char[] { ',' }));
numbers.RemoveAt(numbers.IndexOf(4));
foreach (var n in numbers)
{
    Response.Write(n);
}

Listenizde yinelenen değerler varsa ne olur? Sadece ilk örneği mi yoksa tüm örnekleri mi kaldırmak istiyorsunuz?
BenAlabaster

evet, yinelenen değerlerim yok, bir fikrim var mı?
ahmed

ahmed Bunu mu demek istediniz? (İngilizcinize hakaret etmiyor, sadece açıklama istiyor)
Malfist

@Malfist - özür dilerim :), yinelenen değerleri umursamıyordum çünkü benim durumumda bunlardan herhangi birinin olmadığından eminim, tekrar teşekkürler
ahmed

3
Bu örnek programdan da görebileceğiniz gibi, C # 'daki dizilerden öğe kaldıramazsınız . Yapabileceğiniz yeni bir dizi oluşturmak, orijinalin sadece bazı öğelerini kopyalamak ve orijinal değişkene geri atamaktır. Bütün cevaplarda yapılan budur.
Nicola Musatti

Yanıtlar:


340

Dizini bilmenize gerek kalmadan 4'ün tüm örneklerini kaldırmak istiyorsanız:

LINQ: (.NET Framework 3.5)

int[] numbers = { 1, 3, 4, 9, 2 };
int numToRemove = 4;
numbers = numbers.Where(val => val != numToRemove).ToArray();

LINQ olmayanlar: (.NET Framework 2.0)

static bool isNotFour(int n)
{
    return n != 4;
}

int[] numbers = { 1, 3, 4, 9, 2 };
numbers = Array.FindAll(numbers, isNotFour).ToArray();

Yalnızca ilk örneği kaldırmak istiyorsanız:

LINQ: (.NET Framework 3.5)

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIndex = Array.IndexOf(numbers, numToRemove);
numbers = numbers.Where((val, idx) => idx != numIndex).ToArray();

LINQ olmayanlar: (.NET Framework 2.0)

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int numIdx = Array.IndexOf(numbers, numToRemove);
List<int> tmp = new List<int>(numbers);
tmp.RemoveAt(numIdx);
numbers = tmp.ToArray();

Düzenleme: Malfist'in işaret ettiği gibi, henüz çözemediyseniz, LINQ kod örneklerinin çalışması için .NET Framework 3.5'i hedeflemeniz gerekir. 2.0'ı hedefliyorsanız, LINQ olmayan örneklere başvurmanız gerekir.


32
int[] numbers = { 1, 3, 4, 9, 2 };
numbers = numbers.Except(new int[]{4}).ToArray();

21

Ayrıca dizinizi bir listeye dönüştürebilir ve listeden kaldırmayı çağırabilirsiniz. Daha sonra dizinize geri dönüştürebilirsiniz.

int[] numbers = {1, 3, 4, 9, 2};
var numbersList = numbers.ToList();
numbersList.Remove(4);

11

Soruda yazılan kodun içinde bir hata var

Arraylistiniz "1" "3" "4" "9" ve "2" dizelerini içeriyor (boşluklara dikkat edin)

Böylece IndexOf (4) hiçbir şey bulamayacaktır çünkü 4 int'tir ve "tostring" bile "4" yerine "4" e dönüşür ve hiçbir şey kaldırılmaz.

Bir arraylist istediğini yapmanın doğru yoludur.


<T> listesi ArrayList'ten daha iyi olurdu.
Mike Scott

1
Bu cevap daha fazla oyu hak ediyor. @MikeScott ile List<T>ArrayList'ten daha iyi olacağını kesinlikle kabul etsem de , OP'nin orijinal problemini çözmek için ArrayList'i kullanmaya çalıştığında problemi doğru bir şekilde tanımlayan tek cevap bu gibi görünüyor. OP, kimsenin farketmediği dizileri yeniden boyutlandıramayacağınızı ve bunun yerine başka hiç kimsenin fark etmediği ve daha sonra kimsenin görmediği farklı bir sorunla karşılaştığı yeniden boyutlandırılabilir bir türü kullanmaya çalışamayacağınızı anladı. fark ettim.
phoog

5

Elemanın tüm örneklerini kaldırmak istiyorsanız Balabaster'ın yanıtı doğrudur. Yalnızca ilkini kaldırmak isterseniz, böyle bir şey yaparsınız:

int[] numbers = { 1, 3, 4, 9, 2, 4 };
int numToRemove = 4;
int firstFoundIndex = Array.IndexOf(numbers, numToRemove);
if (numbers >= 0)
{
    numbers = numbers.Take(firstFoundIndex).Concat(numbers.Skip(firstFoundIndex + 1)).ToArray();
}

5

Çözümümü buraya gönderdim .

Bu, aynı dizi örneğinin çerçevesi içinde başka bir diziye kopyalamadan bir dizi öğesini silmenin bir yoludur:

    public static void RemoveAt<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 one
        Array.Resize(ref arr, arr.Length - 1);
    }

4
Resize aslında verileri yeni bir diziye kopyalar (iletilen yeni boyut iletilen dizinin uzunluğu değilse); iletilen dizi örneğinin boyutunu değiştirmez. Bu yüzden bu bir referans parametresidir. Bkz. Referenceource.microsoft.com/mscorlib/R/71074deaf111c4e3.html .
Phoog

5

Bir dizinin kendisini kaldırmak, yeniden boyutlandırma ile uğraşmanız gerektiğinden basit değildir. Bu, List<int>bunun yerine bir şey kullanmanın en büyük avantajlarından biridir . Sağladığı Remove/ RemoveAt2.0 ve 3.0 için LINQ uzantıları bir sürü.

Mümkünse, bir List<>veya benzeri kullanmak için refactor .


Bu durumda en iyi çözüm olduğunu düşünüyorum.
Bogdan Doicin

3

Genel bir uzantı olarak, 2.0 uyumlu:

using System.Collections.Generic;
public static class Extensions {
    //=========================================================================
    // Removes all instances of [itemToRemove] from array [original]
    // Returns the new array, without modifying [original] directly
    // .Net2.0-compatible
    public static T[] RemoveFromArray<T> (this T[] original, T itemToRemove) {  
        int numIdx = System.Array.IndexOf(original, itemToRemove);
        if (numIdx == -1) return original;
        List<T> tmp = new List<T>(original);
        tmp.RemoveAt(numIdx);
        return tmp.ToArray();
    }
}

Kullanımı:

int[] numbers = {1, 3, 4, 9, 2};
numbers = numbers.RemoveFromArray(4);

0

' Sözlük anahtarı değerlerini temel alarak öğeleri dizeden kaldırmak için. 'VB.net kodu

 Dim stringArr As String() = "file1,file2,file3,file4,file5,file6".Split(","c)
 Dim test As Dictionary(Of String, String) = New Dictionary(Of String, String)
 test.Add("file3", "description")
 test.Add("file5", "description")
 stringArr = stringArr.Except(test.Keys).ToArray()

0

Bu şekilde yapabilirsiniz:

int[] numbers= {1,3,4,9,2};     
List<int> lst_numbers = new List<int>(numbers);
int required_number = 4;
int i = 0;
foreach (int number in lst_numbers)
{              
    if(number == required_number)
    {
        break;
    }
    i++;
}
lst_numbers.RemoveAt(i);
numbers = lst_numbers.ToArray();        
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.