Erstatning for for ... Hvis rekke køyring

stemmer
7

Jeg elsker liste oppfattelser i Python, fordi de konsist representerer en transformasjon av en liste.

Men i andre språk, finner jeg ofte meg selv å skrive noe i retning av:

foreach (int x in intArray)
  if (x > 3) //generic condition on x
    x++ 
    //do other processing

Dette eksemplet er i C #, hvor jeg er under inntrykk av LINQ kan hjelpe med dette, men er det noen felles programmerings konstruksjon som kan erstatte dette litt mindre enn elegant løsning? Kanskje en datastruktur jeg ikke vurderer?

Publisert på 16/08/2008 klokken 22:28
kilden bruker
På andre språk...                            


6 svar

stemmer
5

Økningen i den opprinnelige foreachloopen vil ikke påvirke innholdet i array, den eneste måten å gjøre dette er fortsatt en forsløyfe:

for(int i = 0; i < intArray.Length; ++i)
{
    if(intArray[i] > 3) ++intArray[i];
}

Linq er ikke ment for å modifisere eksisterende samlinger eller sekvenser. Det skaper nye sekvenser basert på eksisterende. Det er mulig å oppnå de ovennevnte koden ved hjelp Linq, selv om det er litt mot sin hensikt:

var newArray1 = from i in intArray select ((i > 3) ? (i + 1) : (i));
var newArray2 = intArray.Select(i => (i > 3) ? (i + 1) : (i));

Ved hjelp av where(eller tilsvarende), som vist i noen av de andre svar, vil utelukke alle verdier mindre enn eller lik 3 fra den resulterende sekvens.

var intArray = new int[] { 10, 1, 20, 2 };
var newArray = from i in intArray where i > 3 select i + 1;
// newArray == { 11, 21 }

Det er en ForEachmetode på arrays som vil tillate deg å bruke en lambda funksjon i stedet for en foreachredning for noe mer enn en metode samtale jeg ville feste med foreach.

intArray.ForEach(i => DoSomething(i));
Svarte 17/08/2008 kl. 00:44
kilden bruker

stemmer
2

I C # kan du søke selektiv behandling på noe som lever inni en IEnumerable som dette:

intArray.Where(i => i > 3).ConvertAll();
DoStuff(intArray.Where(i => i 3));

Etc..

Svarte 16/08/2008 kl. 23:06
kilden bruker

stemmer
1

I Python, har du filter og kart , som kan så hva du vil:

map(lambda x: foo(x + 1) filter(lambda x: x > 3, intArray))

Det finnes også liste oppfattelser som kan gjøre begge deler i en enkelt uttalelse:

[f(x + 1) for x in intArray if x > 3]
Svarte 16/08/2008 kl. 22:56
kilden bruker

stemmer
0
map(lambda x: test(x + 1) filter(lambda x: x > 3, arr))
Svarte 25/06/2011 kl. 11:28
kilden bruker

stemmer
0

Ruby:

intArray.select { |x| x > 3 }.each do |x|
  # do other processing
end

eller hvis "annen behandling" er en kort ett-liner:

intArray.select { |x| x > 3 }.each { |x| something_that_uses x }

Til slutt, hvis du ønsker å returnere en ny array som inneholder resultatene av behandlingen av disse elementene større enn 3:

intArray.select { |x| x > 3 }.map { |x| do_something_to x }
Svarte 16/08/2008 kl. 22:47
kilden bruker

stemmer
-1

Avhenger av språk og hva du trenger å gjøre, en "kart" som det heter på mange språk kan være det du leter etter. Jeg vet ikke C #, men ifølge denne siden, .NET 2.0 samtaler kart "ConvertAll".

Betydningen av "kart" er ganske enkel - ta en liste, og bruke en funksjon til hver element av det, tilbake en ny liste. Du kan også være på jakt etter "filter", som vil gi deg en liste over elementer som tilfredsstiller et predikat i en annen liste.

Svarte 16/08/2008 kl. 22:37
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more