web-dev-qa-db-fra.com

Comment remplacer un élément de la liste de la meilleure façon

if (listofelements.Contains(valueFieldValue.ToString()))
{
    listofelements[listofelements.IndexOf(valueFieldValue.ToString())] = value.ToString();
}

J'ai remplacé comme ci-dessus. Existe-t-il un meilleur moyen de comparaison que celui-ci?

62
Ragavan

Utilisez Lambda pour rechercher l'index dans la liste et utilisez cet index pour remplacer l'élément de la liste.

List<string> listOfStrings = new List<string> {"abc", "123", "ghi"};
listOfStrings[listOfStrings.FindIndex(ind=>ind.Equals("123"))] =  "def";
49
rokkuchan

Vous pourriez le rendre plus lisible et plus efficace:

string oldValue = valueFieldValue.ToString();
string newValue = value.ToString();
int index = listofelements.IndexOf(oldValue);
if(index != -1)
    listofelements[index] = newValue;

Cela ne demande qu'une fois l'index. Votre approche utilise d'abord Contains qui doit boucler tous les éléments (dans le pire des cas), puis vous utilisez IndexOf qui doit à nouveau énumérer les éléments.

92
Rango

Vous accédez deux fois à votre liste pour remplacer un élément. Je pense qu'une simple boucle for devrait suffire:

var key = valueFieldValue.ToString();
for (int i = 0; i < listofelements.Count; i++)
{
    if (listofelements[i] == key)
    {
        listofelements[i] = value.ToString();
        break;
    }
}
14
gzaxx

Pourquoi ne pas utiliser les méthodes d'extension?

Considérons le code suivant:

        var intArray = new int[] { 0, 1, 1, 2, 3, 4 };
        // Replaces the first occurance and returns the index
        var index = intArray.Replace(1, 0);
        // {0, 0, 1, 2, 3, 4}; index=1

        var stringList = new List<string> { "a", "a", "c", "d"};
        stringList.ReplaceAll("a", "b");
        // {"b", "b", "c", "d"};

        var intEnum = intArray.Select(x => x);
        intEnum = intEnum.Replace(0, 1);
        // {0, 0, 1, 2, 3, 4} => {1, 1, 1, 2, 3, 4}
  • Pas de code en double 
  • Il n'est pas nécessaire de taper des expressions longues linq
  • Il n'y a pas besoin d'utilisations supplémentaires

Le code source:

namespace System.Collections.Generic
{
    public static class Extensions
    {
        public static int Replace<T>(this IList<T> source, T oldValue, T newValue)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            var index = source.IndexOf(oldValue);
            if (index != -1)
                source[index] = newValue;
            return index;
        }

        public static void ReplaceAll<T>(this IList<T> source, T oldValue, T newValue)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            int index = -1;
            do
            {
                index = source.IndexOf(oldValue);
                if (index != -1)
                    source[index] = newValue;
            } while (index != -1);
        }


        public static IEnumerable<T> Replace<T>(this IEnumerable<T> source, T oldValue, T newValue)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            return source.Select(x => EqualityComparer<T>.Default.Equals(x, oldValue) ? newValue : x);
        }
    }
}

Les deux premières méthodes ont été ajoutées pour modifier les objets des types de référence en place. Bien sûr, vous ne pouvez utiliser que la troisième méthode pour tous les types.

P.S. Grâce à l'observation de mike , j'ai ajouté la méthode ReplaceAll.

8
Ruslan L.

Utilisez FindIndex et lambda pour rechercher et remplacer vos valeurs:

int j = listofelements.FindIndex(i => i.Contains(valueFieldValue.ToString())); //Finds the item index

lstString[j] = lstString[j].Replace(valueFieldValue.ToString(), value.ToString()); //Replaces the item by new value
3
Alex Jolig

Après la réponse de rokkuchan, juste une petite mise à jour:

List<string> listOfStrings = new List<string> {"abc", "123", "ghi"};

int index = listOfStrings.FindIndex(ind => ind.Equals("123"));
if (index > -1)
    listOfStrings[index] =  "def";
2
Fejs

Ou bien, en vous appuyant sur la suggestion de Rusian L., si l'élément que vous recherchez peut figurer plusieurs fois dans la liste:

[Extension()]
public void ReplaceAll<T>(List<T> input, T search, T replace)
{
    int i = 0;
    do {
        i = input.FindIndex(i, s => EqualityComparer<T>.Default.Equals(s, search));

        if (i > -1) {
            FileSystem.input(i) = replace;
            continue;
        }

        break;  
    } while (true);
}
1
mike

Je ne sais pas si c'est mieux ou pas, mais vous pouvez aussi l'utiliser

List<string> data = new List<string>
(new string[]   { "Computer", "A", "B", "Computer", "B", "A" });
int[] indexes = Enumerable.Range(0, data.Count).Where
                 (i => data[i] == "Computer").ToArray();
Array.ForEach(indexes, i => data[i] = "Calculator");
1
Nik

je trouve le mieux pour le faire vite et simple

  1. trouver votre article dans la liste

    var d = Details.Where(x => x.ProductID == selectedProduct.ID).SingleOrDefault();
    
  2. faire un clone de courant

    OrderDetail dd = d;
    
  3. Mettre à jour votre clone

    dd.Quantity++;
    
  4. trouver l'index dans la liste

    int idx = Details.IndexOf(d);
    
  5. supprimer l'élément trouvé dans (1)

      Details.Remove(d);
    
  6. insérer

     if (idx > -1)
          Details.Insert(idx, dd);
      else
          Details.Insert(Details.Count, dd);
    
0
Tarrah Arshad

Je pense qu’il est préférable d’utiliser ObservableCollection au lieu de List, et de le convertir en liste lorsque nous avons besoin de l’aligner . Avec une collection observable, vous pouvez supprimer et ajouter un élément sur deux lignes, obtenir cette fonctionnalité en utilisant une liste . ce lien peut donner une idée précise de ObservableCollection <> vs. List <>

0
MNF