2013-03-13 20 views
5

C'è un modo per effettuare le seguenti operazioni utilizzando Linq:aggiornare tutti gli oggetti tranne uno in una collezione utilizzando Linq

foreach (var c in collection) 
{ 
    if (c.Condition == condition) 
    { 
     c.PropertyToSet = value; 
     // I must also check I only set this value to one minimum and only one element. 
    } 
    else 
    { 
     c.PropertyToSet = otherValue; 
    } 
} 

Per chiarire, io voglio scorrere ogni oggetto in una collezione e quindi aggiornare una proprietà su ogni oggetto ad eccezione di un elemento della mia collezione che dovrebbe essere aggiornato ad un altro valore.

In questo momento, utilizzo un contatore per verificare di impostare il mio valore su uno e solo un elemento della mia raccolta. L'ho rimosso da questo esempio per permettere alle persone di suggerire altre soluzioni.

La domanda originale, senza eccezione, in collezione è here

EDIT

pongo questa domanda perché io non sono sicuro che sia possibile farlo con LINQ. quindi le tue risposte confortano la mia opinione su LinQ. Grazie.

+2

Stai modificando la tua raccolta originale o desideri restituire una copia con tale proprietà modificata? –

+0

Sto cambiando la mia collezione. qual è la differenza? –

+0

Che tipo di collezione è questa .. È una Hashtable, un dizionario <>, una lista <>, ecc., Per favore chiarisci che tipo di collezione è questa.puoi farlo usando un Hashtable o un dizionario <> puoi mostrare come è definita la collezione – MethodMan

risposta

7

È possibile utilizzare .ForEach per apportare la modifica, e .Single per verificare un solo elemento corrisponde la condizione:

// make sure only one item matches the condition 
var singleOne = collection.Single(c => c.Condition == condition); 
singleOne.PropertyToSet = value; 

// update the rest of the items 
var theRest = collection.Where(c => c.Condition != condition); 
theRest.ToList().ForEach(c => c.PropertyToSet = otherValue); 
+0

che risponda alla mia domanda ma non sia la soluzione migliore da implementare. leggi altri post per scegliere il tuo. Grazie. –

2
collection.Where(x => <condition>).ToList().ForEach(x => <action>); 
5

Non ti suggerisco di implementare questo con LINQ. Perché? Perché Linq è per l'interrogazione, non per la modifica. Può restituire oggetti che corrispondono ad alcune condizioni o oggetti che non corrispondono. Ma per l'aggiornamento di tali oggetti è ancora necessario utilizzare foreach o convertire i risultati della query in elenco e utilizzare l'estensione ForEach. Entrambi richiedono la sequenza di numerazione due volte.

Così, semplice ciclo farà il lavoro:

foreach (var c in collection) 
{ 
    c.PropertyToSet = (c.Condition == condition) ? value : otherValue; 
} 
0

Beh, si potrebbe fare:

var itemToSetValue = collection.FirstOrDefault(c => c.Condition == condition); 

if(itemToSetValue != null) 
    itemToSetValue.PropertyToSet = value; 

// Depending on what you mean, this predicate 
// might be c => c != itemToSetValue instead. 
foreach (var otherItem in collection.Where(c => c.Condition != condition)) 
{ 
    otherItem.PropertyToSet = otherValue; 
} 

Ora, naturalmente, che non è una soluzione LINQ pura, ma pure le soluzioni LINQ non sono appropriati per modificare collezioni esistenti.

2

modo Hacky usare LINQ se persistono da usare:

var result = collection.Select(c => 
{ 
    c.PropertyToSet = c.Condition == condition ? value : otherValue; 
    return c; 
}); 

Ma la mia raccomandazione, non fare questo, è il codice effettivamente ottenere l'approccio migliore, per più leggibilità, è possibile modificare:

foreach (var c in collection) 
    c.PropertyToSet = c.Condition == condition ? value : otherValue; 
+0

È potenzialmente pericoloso se si passa l'IEnumerable non numerato. Se la riga 'c.PropertyToSet ...' non è idempotente, l'iterazione "accidentalmente" più di una volta produrrebbe risultati imprevisti. –

2

è possibile utilizzare un operatore ternario in combinazione con una dichiarazione LINQ:

collection.ToList().ForEach(c => c.PropertyToSet = c.Condition == condition ? value : otherValue); 

Tuttavia, dovrei semplicemente usare un foreach regolare qui per evitare di convertire la raccolta in una lista.

Problemi correlati