Aktualisieren Sie alle Objekte in einer Sammlung mit LINQ

500

Gibt es eine Möglichkeit, mit LINQ Folgendes zu tun?

foreach (var c in collection)
{
    c.PropertyToSet = value;
}

Zur Verdeutlichung möchte ich jedes Objekt in einer Sammlung durchlaufen und dann eine Eigenschaft für jedes Objekt aktualisieren.

Mein Anwendungsfall ist, dass ich eine Reihe von Kommentaren zu einem Blog-Beitrag habe. Ich möchte jeden Kommentar in einem Blog-Beitrag durchlaufen und die Datums- und Uhrzeitangabe für den Blog-Beitrag auf +10 Stunden festlegen. Ich könnte es in SQL tun, aber ich möchte es in der Geschäftsschicht behalten.

Lomaxx
quelle
14
Interessante Frage. Persönlich bevorzuge ich, wie Sie es oben haben - viel klarer, was los ist!
Noelicus
8
Ich kam hierher, um nach einer Antwort auf dieselbe Frage zu suchen, und entschied, dass es für zukünftige Entwickler genauso einfach, weniger Code und einfacher zu verstehen ist, es einfach so zu machen, wie Sie es in Ihrem OP getan haben.
Casey Crookston
4
Warum sollten Sie dies in LINQ tun?
Caltor
13
Diese Frage fragt nach dem Falschen, die einzig richtige Antwort lautet: Verwenden Sie LINQ nicht, um die Datenquelle zu ändern
Tim Schmelter
Ich stimme dafür, diese Frage als nicht zum Thema gehörend zu schließen, da fast alle Antworten auf diese Frage das Verständnis neuer Programmierer für LINQ aktiv beeinträchtigen.
Tanveer Badar

Antworten:

842

Sie können zwar eine ForEachErweiterungsmethode verwenden, aber wenn Sie nur das Framework verwenden möchten, können Sie dies tun

collection.Select(c => {c.PropertyToSet = value; return c;}).ToList();

Das ToListwird benötigt, um die Auswahl aufgrund der verzögerten Auswertung sofort auszuwerten .

Cameron MacFarland
quelle
6
Ich habe dies positiv bewertet, weil es eine ziemlich nette Lösung ist. Der einzige Grund, warum ich die Erweiterungsmethode mag, ist, dass es ein wenig klarer ist, genau zu verstehen, was vor sich geht. Ihre Lösung ist jedoch immer noch ziemlich süß
lomaxx
9
Wenn die Sammlung ein ObservableCollectionMitspracherecht war, kann es hilfreich sein, Elemente an Ort und Stelle zu ändern, anstatt eine neue Liste zu erstellen.
Cameron MacFarland
7
@desaivv Ja, das ist ein bisschen ein Syntaxmissbrauch, also warnt Resharper Sie davor.
Cameron MacFarland
46
IMHO ist dies weit weniger aussagekräftig als eine einfache foreach-Schleife. Die ToList () ist verwirrend, da sie nur zum Erzwingen einer Auswertung verwendet wird, die sonst zurückgestellt würde. Die Projektion ist auch verwirrend, weil sie nicht für den beabsichtigten Zweck verwendet wird. Stattdessen wird es verwendet, um die Elemente der Sammlung zu durchlaufen und den Zugriff auf eine Eigenschaft zu ermöglichen, damit diese aktualisiert werden kann. Die einzige Frage in meinem Kopf wäre, ob die foreach-Schleife von Parallelität mit Parallel.ForEach profitieren könnte oder nicht, aber das ist eine andere Frage.
Philippe
37
Diese Antwort ist eine schlechteste Praxis. Mach das niemals.
Eric Lippert
351
collection.ToList().ForEach(c => c.PropertyToSet = value);
Ε Г И І І О
quelle
36
@ SantoshKumar: Verwenden Siecollection.ToList().ForEach(c => { c.Property1ToSet = value1; c.Property2ToSet = value2; });
Г И І І О
@CameronMacFarland: Natürlich nicht, da Strukturen unveränderlich sind. Aber wenn Sie wirklich wollen, können Sie dies tun:collection.ToList().ForEach(c => { collection[collection.IndexOf(c)] = new <struct type>() { <propertyToSet> = value, <propertyToRetain> = c.Property2Retain }; });
О Г И І І О
11
Dies hat gegenüber Cameron MacFarlands Antwort den Vorteil, dass die Liste aktualisiert wird, anstatt eine neue Liste zu erstellen.
Simon Tewsi
7
Wow, diese Antwort ist wirklich nicht nützlich. Erstellen einer neuen Sammlung, nur um eine Schleife verwenden zu können
Tim Schmelter
@SimonTewsi Da es sich um eine Sammlung von Objekten handelt, sollte die Liste trotzdem aktualisiert werden. Die Sammlung ist neu, aber die Objekte in der Sammlung sind dieselben.
Chris
70

Ich mache das

Collection.All(c => { c.needsChange = value; return true; });
Rahul
quelle
Ich denke, das ist der sauberste Weg, es zu tun.
wcm
31
Dieser Ansatz funktioniert zwar, verstößt jedoch gegen die Absicht der All()Erweiterungsmethode und kann zu Verwirrung führen, wenn jemand anderes den Code liest.
Tom Baxter
Dieser Ansatz ist besser. Alle verwenden, anstatt jede Schleife zu verwenden
UJS
2
Ziehen Sie dies auf jeden Fall dem unnötigen Aufruf von ToList () vor, auch wenn es etwas irreführend ist, wofür All () verwendet wird.
Iupchris10
1
Wenn Sie eine solche Sammlung verwenden List<>, ist die ForEach()Methode eine viel weniger kryptische Methode, um dies zu erreichen. ExForEach(c => { c.needsChange = value; })
Dan spielt am Feuer
27

Ich habe tatsächlich eine Erweiterungsmethode gefunden, die das macht, was ich will

public static IEnumerable<T> ForEach<T>(
    this IEnumerable<T> source,
    Action<T> act)
{
    foreach (T element in source) act(element);
    return source;
}
Lomaxx
quelle
4
nett :) Lomaxx, füge vielleicht ein Beispiel hinzu, damit die Leute es in 'Action' sehen können (Boom Tish!).
Pure.Krome
2
Dies ist der einzig nützliche Ansatz, wenn Sie eine foreachSchleife wirklich vermeiden möchten (aus welchem ​​Grund auch immer).
Tim Schmelter
@ Rango, den Sie immer noch NICHT vermeiden, foreachda der Code selbst die foreachSchleife enthält
GoldBishop
@ GoldBishop sicher, die Methode verbirgt die Schleife.
Tim Schmelter
1
Der Link ist defekt und jetzt verfügbar unter: codewrecks.com/blog/index.php/2008/08/13/… . Es gibt auch einen Blog-Kommentar, der auf stackoverflow.com/questions/200574 verweist . Der Kommentar zur obersten Frage verweist wiederum auf blogs.msdn.microsoft.com/ericlippert/2009/05/18/… . Vielleicht wäre die Antwort einfacher, wenn Sie sie mit dem MSDN neu schreiben würden (Sie könnten den ersten Link trotzdem gutschreiben, wenn Sie möchten). Nebenbemerkung: Rust hat ähnliche Funktionen und gab schließlich nach und fügte die entsprechende Funktion hinzu: stackoverflow.com/a/50224248/799204
sourcejedi
15

Verwenden:

ListOfStuff.Where(w => w.Thing == value).ToList().ForEach(f => f.OtherThing = vauleForNewOtherThing);

Ich bin nicht sicher, ob dies LINQ überbeansprucht oder nicht, aber es hat bei mir funktioniert, wenn ich bestimmte Elemente in der Liste für eine bestimmte Bedingung aktualisieren möchte.

Hennish
quelle
7

Hierfür gibt es keine integrierte Erweiterungsmethode. Obwohl die Definition eines ziemlich einfach ist. Am Ende des Beitrags befindet sich eine von mir definierte Methode namens Iterate. Es kann so verwendet werden

collection.Iterate(c => { c.PropertyToSet = value;} );

Quelle iterieren

public static void Iterate<T>(this IEnumerable<T> enumerable, Action<T> callback)
{
    if (enumerable == null)
    {
        throw new ArgumentNullException("enumerable");
    }

    IterateHelper(enumerable, (x, i) => callback(x));
}

public static void Iterate<T>(this IEnumerable<T> enumerable, Action<T,int> callback)
{
    if (enumerable == null)
    {
        throw new ArgumentNullException("enumerable");
    }

    IterateHelper(enumerable, callback);
}

private static void IterateHelper<T>(this IEnumerable<T> enumerable, Action<T,int> callback)
{
    int count = 0;
    foreach (var cur in enumerable)
    {
        callback(cur, count);
        count++;
    }
}
JaredPar
quelle
Ist Iterieren notwendig, was ist falsch an Count, Sum, Avg oder einer anderen vorhandenen Erweiterungsmethode, die einen Skalarwert zurückgibt?
AnthonyWJones
2
Das ist ziemlich nah an dem, was ich will, aber ein wenig ... involviert. Der Blog-Beitrag, den ich gepostet habe, hat eine ähnliche Implementierung, aber weniger Codezeilen.
Lomaxx
1
Der IterateHelper scheint übertrieben. Die Überlastung, die keinen Index benötigt, führt zu viel mehr zusätzlicher Arbeit (Konvertieren Sie den Rückruf in Lambda, das den Index benötigt, behalten Sie eine Zählung bei, die niemals verwendet wird). Ich verstehe, dass es wiederverwendet wird, aber es ist eine Problemumgehung für die Verwendung eines Forloops, sodass es effizient sein sollte.
Cameron MacFarland
2
@Cameron, IterateHelper dient zwei Zwecken. 1) Einzelne Implementierung und 2) Ermöglichen, dass ArgumentNullException zur Aufrufzeit im Vergleich zur Verwendung ausgelöst wird. C # -Iteratoren werden verzögert ausgeführt, da der Helfer verhindert, dass das seltsame Verhalten einer Ausnahme während der Iteration ausgelöst wird.
JaredPar
2
@JaredPar: Außer du verwendest keinen Iterator. Es gibt keine Renditeerklärung.
Cameron MacFarland
7

Obwohl Sie speziell nach einer LINQ-Lösung gefragt haben und diese Frage ziemlich alt ist, poste ich eine Nicht-LINQ-Lösung. Dies liegt daran, dass LINQ (= sprachintegrierte Abfrage ) für Abfragen in Sammlungen verwendet werden soll. Alle LINQ-Methoden haben die zugrunde liegende Sammlung nicht ändern, sie einfach zurückgeben einen neuen (oder genauer gesagt einen Iterator auf eine neue Sammlung). Was auch immer Sie tun, z. B. mit a, Selectwirkt sich nicht auf die zugrunde liegende Sammlung aus, Sie erhalten einfach eine neue.

Natürlich könnten Sie es mit einem machen ForEach(was übrigens nicht LINQ ist, sondern eine Erweiterung auf List<T>). Aber das buchstäblich verwendet foreachsowieso, aber mit einem Lambda-Ausdruck. Abgesehen davon iteriert jede LINQ-Methode Ihre Sammlung intern, z. B. mithilfe von foreachoder for, verbirgt sie jedoch einfach vor dem Client. Ich halte dies nicht für lesbarer oder wartbarer (denken Sie daran, Ihren Code zu bearbeiten, während Sie eine Methode debuggen, die Lambda-Ausdrücke enthält).

Allerdings sollte LINQ nicht zum Ändern von Elementen in Ihrer Sammlung verwendet werden. Ein besserer Weg ist die Lösung, die Sie bereits in Ihrer Frage angegeben haben. Mit einer klassischen Schleife können Sie Ihre Sammlung einfach iterieren und ihre Elemente aktualisieren. Tatsächlich sind all diese Lösungen, auf die man sich stützt, List.ForEachnichts anderes, aber aus meiner Sicht weitaus schwieriger zu lesen.

Daher sollten Sie LINQ nicht in den Fällen verwenden, in denen Sie die Elemente Ihrer Sammlung aktualisieren möchten .

HimBromBeere
quelle
3
Off-Topic: Ich stimme zu, und es gibt sooooooo viele Fälle von Missbrauch von LINQ, Beispiele von Personen, die "Hochleistungs-LINQ-Ketten" anfordern, um das zu tun, was mit einer einzigen Schleife erreicht werden könnte usw. Ich bin dankbar, dass LINQ NICHT verwendet wird zu tief in mir verwurzelt und benutze es normalerweise nicht. Ich sehe Leute, die LINQ-Ketten verwenden, um eine einzelne Aktion auszuführen, ohne zu bemerken, dass Sie so ziemlich jedes Mal, wenn ein LINQ-Befehl verwendet wird, eine weitere forSchleife "unter der Haube" erstellen . Ich halte es für syntatischen Zucker, weniger ausführliche Methoden für einfache Aufgaben zu entwickeln und nicht die Standardcodierung zu ersetzen.
ForeverZer0
6

Ich habe ein paar Variationen davon ausprobiert und gehe immer wieder auf die Lösung dieses Typen zurück.

http://www.hookedonlinq.com/UpdateOperator.ashx

Auch dies ist die Lösung eines anderen. Aber ich habe den Code in eine kleine Bibliothek kompiliert und verwende ihn ziemlich regelmäßig.

Ich werde seinen Code hier einfügen, damit seine Website (Blog) irgendwann nicht mehr existiert. (Es gibt nichts Schlimmeres als einen Beitrag mit den Worten "Hier ist die genaue Antwort, die Sie benötigen", "Klicken" und "Tote URL".)

    public static class UpdateExtensions {

    public delegate void Func<TArg0>(TArg0 element);

    /// <summary>
    /// Executes an Update statement block on all elements in an IEnumerable<T> sequence.
    /// </summary>
    /// <typeparam name="TSource">The source element type.</typeparam>
    /// <param name="source">The source sequence.</param>
    /// <param name="update">The update statement to execute for each element.</param>
    /// <returns>The numer of records affected.</returns>
    public static int Update<TSource>(this IEnumerable<TSource> source, Func<TSource> update)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (update == null) throw new ArgumentNullException("update");
        if (typeof(TSource).IsValueType)
            throw new NotSupportedException("value type elements are not supported by update.");

        int count = 0;
        foreach (TSource element in source)
        {
            update(element);
            count++;
        }
        return count;
    }
}



int count = drawingObjects
        .Where(d => d.IsSelected && d.Color == Colors.Blue)
        .Update(e => { e.Color = Color.Red; e.Selected = false; } );
granadaCoder
quelle
1
Sie können einen verwenden, Action<TSource>anstatt einen zusätzlichen Delegaten zu erstellen. Dies war jedoch zum Zeitpunkt des Schreibens möglicherweise noch nicht verfügbar.
Frank J
Ja, das war zu diesem Zeitpunkt DotNet der alten Schule. Guter Kommentar Frank.
GranadaCoder
Die URL ist tot! (Dieser Domain Name ist abgelaufen) Gut, dass ich den Code hier kopiert habe! #patOnShoulder
granadaCoder
1
Das Überprüfen des Werttyps ist sinnvoll, aber möglicherweise ist es besser, eine Einschränkung zu verwenden, dh where T: structdiese beim Kompilieren abzufangen.
Groo
3

Ich habe einige Erweiterungsmethoden geschrieben, um mir dabei zu helfen.

namespace System.Linq
{
    /// <summary>
    /// Class to hold extension methods to Linq.
    /// </summary>
    public static class LinqExtensions
    {
        /// <summary>
        /// Changes all elements of IEnumerable by the change function
        /// </summary>
        /// <param name="enumerable">The enumerable where you want to change stuff</param>
        /// <param name="change">The way you want to change the stuff</param>
        /// <returns>An IEnumerable with all changes applied</returns>
        public static IEnumerable<T> Change<T>(this IEnumerable<T> enumerable, Func<T, T> change  )
        {
            ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
            ArgumentCheck.IsNullorWhiteSpace(change, "change");

            foreach (var item in enumerable)
            {
                yield return change(item);
            }
        }

        /// <summary>
        /// Changes all elements of IEnumerable by the change function, that fullfill the where function
        /// </summary>
        /// <param name="enumerable">The enumerable where you want to change stuff</param>
        /// <param name="change">The way you want to change the stuff</param>
        /// <param name="where">The function to check where changes should be made</param>
        /// <returns>
        /// An IEnumerable with all changes applied
        /// </returns>
        public static IEnumerable<T> ChangeWhere<T>(this IEnumerable<T> enumerable, 
                                                    Func<T, T> change,
                                                    Func<T, bool> @where)
        {
            ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
            ArgumentCheck.IsNullorWhiteSpace(change, "change");
            ArgumentCheck.IsNullorWhiteSpace(@where, "where");

            foreach (var item in enumerable)
            {
                if (@where(item))
                {
                    yield return change(item);
                }
                else
                {
                    yield return item;
                }
            }
        }

        /// <summary>
        /// Changes all elements of IEnumerable by the change function that do not fullfill the except function
        /// </summary>
        /// <param name="enumerable">The enumerable where you want to change stuff</param>
        /// <param name="change">The way you want to change the stuff</param>
        /// <param name="where">The function to check where changes should not be made</param>
        /// <returns>
        /// An IEnumerable with all changes applied
        /// </returns>
        public static IEnumerable<T> ChangeExcept<T>(this IEnumerable<T> enumerable,
                                                     Func<T, T> change,
                                                     Func<T, bool> @where)
        {
            ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
            ArgumentCheck.IsNullorWhiteSpace(change, "change");
            ArgumentCheck.IsNullorWhiteSpace(@where, "where");

            foreach (var item in enumerable)
            {
                if (!@where(item))
                {
                    yield return change(item);
                }
                else
                {
                    yield return item;
                }
            }
        }

        /// <summary>
        /// Update all elements of IEnumerable by the update function (only works with reference types)
        /// </summary>
        /// <param name="enumerable">The enumerable where you want to change stuff</param>
        /// <param name="update">The way you want to change the stuff</param>
        /// <returns>
        /// The same enumerable you passed in
        /// </returns>
        public static IEnumerable<T> Update<T>(this IEnumerable<T> enumerable,
                                               Action<T> update) where T : class
        {
            ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
            ArgumentCheck.IsNullorWhiteSpace(update, "update");
            foreach (var item in enumerable)
            {
                update(item);
            }
            return enumerable;
        }

        /// <summary>
        /// Update all elements of IEnumerable by the update function (only works with reference types)
        /// where the where function returns true
        /// </summary>
        /// <param name="enumerable">The enumerable where you want to change stuff</param>
        /// <param name="update">The way you want to change the stuff</param>
        /// <param name="where">The function to check where updates should be made</param>
        /// <returns>
        /// The same enumerable you passed in
        /// </returns>
        public static IEnumerable<T> UpdateWhere<T>(this IEnumerable<T> enumerable,
                                               Action<T> update, Func<T, bool> where) where T : class
        {
            ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
            ArgumentCheck.IsNullorWhiteSpace(update, "update");
            foreach (var item in enumerable)
            {
                if (where(item))
                {
                    update(item);
                }
            }
            return enumerable;
        }

        /// <summary>
        /// Update all elements of IEnumerable by the update function (only works with reference types)
        /// Except the elements from the where function
        /// </summary>
        /// <param name="enumerable">The enumerable where you want to change stuff</param>
        /// <param name="update">The way you want to change the stuff</param>
        /// <param name="where">The function to check where changes should not be made</param>
        /// <returns>
        /// The same enumerable you passed in
        /// </returns>
        public static IEnumerable<T> UpdateExcept<T>(this IEnumerable<T> enumerable,
                                               Action<T> update, Func<T, bool> where) where T : class
        {
            ArgumentCheck.IsNullorWhiteSpace(enumerable, "enumerable");
            ArgumentCheck.IsNullorWhiteSpace(update, "update");

            foreach (var item in enumerable)
            {
                if (!where(item))
                {
                    update(item);
                }
            }
            return enumerable;
        }
    }
}

Ich benutze es so:

        List<int> exampleList = new List<int>()
            {
                1, 2 , 3
            };

        //2 , 3 , 4
        var updated1 = exampleList.Change(x => x + 1);

        //10, 2, 3
        var updated2 = exampleList
            .ChangeWhere(   changeItem => changeItem * 10,          // change you want to make
                            conditionItem => conditionItem < 2);    // where you want to make the change

        //1, 0, 0
        var updated3 = exampleList
            .ChangeExcept(changeItem => 0,                          //Change elements to 0
                          conditionItem => conditionItem == 1);     //everywhere but where element is 1

Als Referenz überprüfen Sie das Argument:

/// <summary>
/// Class for doing argument checks
/// </summary>
public static class ArgumentCheck
{


    /// <summary>
    /// Checks if a value is string or any other object if it is string
    /// it checks for nullorwhitespace otherwhise it checks for null only
    /// </summary>
    /// <typeparam name="T">Type of the item you want to check</typeparam>
    /// <param name="item">The item you want to check</param>
    /// <param name="nameOfTheArgument">Name of the argument</param>
    public static void IsNullorWhiteSpace<T>(T item, string nameOfTheArgument = "")
    {

        Type type = typeof(T);
        if (type == typeof(string) ||
            type == typeof(String))
        {
            if (string.IsNullOrWhiteSpace(item as string))
            {
                throw new ArgumentException(nameOfTheArgument + " is null or Whitespace");
            }
        }
        else
        {
            if (item == null)
            {
                throw new ArgumentException(nameOfTheArgument + " is null");
            }
        }

    }
}
PartTimeIndie
quelle
2

Meine 2 Pennies: -

 collection.Count(v => (v.PropertyToUpdate = newValue) == null);
AnthonyWJones
quelle
7
Ich mag das Denken, aber es ist nicht wirklich klar, was der Code tut
lomaxx
2

Sie können LINQ verwenden, um Ihre Sammlung in ein Array zu konvertieren und dann Array.ForEach () aufzurufen:

Array.ForEach(MyCollection.ToArray(), item=>item.DoSomeStuff());

Offensichtlich funktioniert dies nicht mit Sammlungen von Strukturen oder eingebauten Typen wie Ganzzahlen oder Zeichenfolgen.

Tamas Czinege
quelle
1

Hier ist die Erweiterungsmethode, die ich verwende ...

    /// <summary>
    /// Executes an Update statement block on all elements in an  IEnumerable of T
    /// sequence.
    /// </summary>
    /// <typeparam name="TSource">The source element type.</typeparam>
    /// <param name="source">The source sequence.</param>
    /// <param name="action">The action method to execute for each element.</param>
    /// <returns>The number of records affected.</returns>
    public static int Update<TSource>(this IEnumerable<TSource> source, Func<TSource> action)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (action == null) throw new ArgumentNullException("action");
        if (typeof (TSource).IsValueType)
            throw new NotSupportedException("value type elements are not supported by update.");

        var count = 0;
        foreach (var element in source)
        {
            action(element);
            count++;
        }
        return count;
    }
Bill Forney
quelle
Warum "Werttypelemente werden vom Update nicht unterstützt"? Nichts stört das!
Abatishchev
Das war spezifisch für das Projekt, an dem ich arbeitete. Ich nehme an, dass es in den meisten Fällen keine Rolle spielt. In letzter Zeit habe ich das überarbeitet und in Run (...) umbenannt, den Werttyp entfernt und ihn so geändert, dass er void zurückgibt, und den Zählcode gelöscht.
Bill Forney
Das ist mehr oder weniger das, was es List<T>.ForEachauch tut, aber nur für alle IEnumerable.
HimBromBeere
Wenn ich jetzt zurückblicke, würde ich sagen, benutze einfach eine foreach-Schleife. Der einzige Vorteil dieser Verwendung besteht darin, dass Sie die Methoden miteinander verketten und die Aufzählung von der Funktion zurückgeben möchten, um die Kette nach dem Ausführen der Aktion fortzusetzen. Andernfalls ist dies nur ein zusätzlicher Methodenaufruf ohne Nutzen.
Bill Forney
0

Ich gehe davon aus, dass Sie Werte innerhalb einer Abfrage ändern möchten, damit Sie eine Funktion dafür schreiben können

void DoStuff()
{
    Func<string, Foo, bool> test = (y, x) => { x.Bar = y; return true; };
    List<Foo> mylist = new List<Foo>();
    var v = from x in mylist
            where test("value", x)
            select x;
}

class Foo
{
    string Bar { get; set; }
}

Aber nicht sicher, ob du das meinst.

Stormenet
quelle
Dies geht in die richtige Richtung, indem es etwas erfordert, um v aufzuzählen, sonst wird es nichts tun.
AnthonyWJones
-3

Angenommen, wir haben Daten wie unten,

var items = new List<string>({"123", "456", "789"});
// Like 123 value get updated to 123ABC ..

und wenn wir die Liste ändern und die vorhandenen Werte der Liste durch geänderte Werte ersetzen möchten, erstellen Sie zuerst eine neue leere Liste und durchlaufen dann die Datenliste, indem Sie die Änderungsmethode für jedes Listenelement aufrufen.

var modifiedItemsList = new List<string>();

items.ForEach(i => {
  var modifiedValue = ModifyingMethod(i);
  modifiedItemsList.Add(items.AsEnumerable().Where(w => w == i).Select(x => modifiedValue).ToList().FirstOrDefault()?.ToString()) 
});
// assign back the modified list
items = modifiedItemsList;
Vishwa G.
quelle
2
Warum sollten Sie etwas, das in O (n) Laufzeit laufen kann, in O (n ^ 2) oder schlechter ausführen lassen? Ich weiß nicht, wie die Besonderheiten von Linq funktionieren, aber ich kann sehen, dass dies mindestens eine ^ 2-Lösung für ein n- Problem ist.
Fallenreaper