2008-08-16 2 views
6

Я люблю списки в Python, потому что они кратко представляют преобразование списка.Замена для ... if array iteration

Однако на других языках, я часто ловлю себя писать что-то вдоль линий:

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

Этот пример находится в C#, где я нахожусь под впечатлением LINQ может помочь с этим, но есть какую-то общую конструкцию программирования, которая может заменить это немного менее элегантное решение? Возможно, структура данных, которую я не рассматриваю?

ответ

5

приращение оригинальный foreach цикл не будет влиять на содержимое массива, единственный способ сделать это остается for петли:

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

Linq не предназначен для изменения существующих коллекций или последовательностей. Он создает новые последовательности на основе существующих. Можно достичь выше кода с помощью Linq, хотя это немного против своих целей:

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

Использование where (или эквивалент), как показано в некоторых других ответов, исключит любые значения меньше или равно до 3 из полученной последовательности.

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

Существует ForEach метода массивов, что позволит Вам использовать функцию лямбды вместо foreach блока, хотя на нечто большее, чем вызов метода я бы придерживаться foreach.

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

В зависимости от языка и того, что вам нужно сделать, «карта», как ее называют на многих языках, может быть тем, что вы ищете. Я не знаю C#, но согласно странице this, .NET 2.0 называет карту «ConvertAll».

Значение «карты» довольно просто - возьмите список и примените функцию к каждому элементу, возвращая новый список. Вы также можете искать «фильтр», который предоставит вам список элементов, которые удовлетворяют предикату в другом списке.

0

в Ruby:

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

или «другая обработка» короткий один лайнер:

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

наконец, если вы хотите, чтобы вернуть новый массив, содержащий результаты обработки из этих элементов больше, чем 3:

intArray.select { |x| x > 3 }.map { |x| do_something_to x } 
1

в Python, у вас есть filter and map, ш Хич можете так, что вы хотите:

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

Там также list comprehensions, которые могут сделать оба в одном легком высказывания:

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

В C# можно применять селективную обработку всего, что живет внутри IEnumerable, как это:

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

Etc ..

0
map(lambda x: test(x + 1) filter(lambda x: x > 3, arr))