Question

J'adore les compréhensions de listes en Python, car elles représentent de manière concise une transformation d'une liste.

Cependant, dans d’autres langues, je me retrouve fréquemment à écrire quelque chose du genre :

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

Cet exemple est en C#, où j'ai l'impression que LINQ peut vous aider, mais existe-t-il une construction de programmation commune qui peut remplacer cette solution légèrement moins élégante ?Peut-être une structure de données que je n'envisage pas ?

Était-ce utile?

La solution

L'incrément dans l'original foreach la boucle n'affectera pas le contenu du tableau, la seule façon de le faire reste un for boucle:

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

Linq n'est pas destiné à modifier les collections ou séquences existantes.Il crée de nouvelles séquences basées sur celles existantes.Il est possible d'obtenir le code ci-dessus en utilisant Linq, bien que cela soit légèrement contraire à son objectif :

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

En utilisant where (ou équivalent), comme indiqué dans certaines des autres réponses, exclura toutes les valeurs inférieures ou égales à 3 de la séquence résultante.

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

Il y a un ForEach méthode sur les tableaux qui vous permettra d'utiliser une fonction lambda au lieu d'un foreach bloc, mais pour autre chose qu'un appel de méthode, je m'en tiendrai à foreach.

intArray.ForEach(i => DoSomething(i));

Autres conseils

En C#, vous pouvez appliquer un traitement sélectif sur tout ce qui se trouve à l'intérieur d'un IEnumerable comme ceci :

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

Etc..

En Python, vous avez filtrer et cartographier, ce qui peut faire ce que vous voulez :

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

Il y a aussi compréhensions de listes qui peut faire les deux en une seule déclaration simple :

[f(x + 1) for x in intArray if x > 3]

en Ruby :

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

ou si « autre traitement » est une courte phrase :

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

enfin, si vous souhaitez renvoyer un nouveau tableau contenant les résultats du traitement des éléments supérieurs à 3 :

intArray.select { |x| x > 3 }.map { |x| do_something_to x }
map(lambda x: test(x + 1) filter(lambda x: x > 3, arr))

Cela dépend de la langue et de ce que vous devez faire, une « carte », comme on l'appelle dans de nombreuses langues, pourrait être ce que vous recherchez.Je ne connais pas C#, mais d'après ce page, .NET 2.0 appelle la carte "ConvertAll".

La signification de « carte » est assez simple : prenez une liste et appliquez une fonction à chaque élément de celle-ci, renvoyant une nouvelle liste.Vous recherchez peut-être également "filtre", qui vous donnerait une liste d'éléments qui satisfont à un prédicat dans une autre liste.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top