2015-04-04 6 views
1

У меня есть 2 результата запроса Linq, с которыми я хочу сделать некоторые строковые операции и объединить.Конкатенация коллекций IEnumerable C#

Результат 1, который является имена разрешенных флажков из group1, полученный

var selectedCarPosts = grpBox1MCar.Controls.OfType<CheckBox>() 
.Where(c => c.Checked).OrderBy(c => c.Name).Select(c => c.Name); 

, который дает результат 1:

NearMainGate 
NearMP5WestGate 

Результат 2, который является имена разрешенных флажков из group2, obtainedby

var selectedDtTypeCars = gbDataTypeMCars.Controls.OfType<CheckBox>() 
.Where(c => c.Checked).OrderBy(c => c.Name).Select(c => c.Name); 

, который дает result2:

WindDir 
WindVel 

Из обоих результатов хотелось бы получить каскадный список следующим образом: (Result3)

C.NearMainGate 
C.NearMP5WestGate 
C.WindDirNearMainGate 
C.WindDirNearMP5WestGate 
C.WindVelNearMainGate 
C.WindVelNearMP5WestGate 

Эти формы столбцов в динамическом запросе SQL позже.

У меня есть следующий код, чтобы выполнить этот шаг за шагом:

var s1 = selectedCarPosts.Select(s => "C." + s); //the first 2 items in Result3 
//Now to get the rest, by inserting Result2 string in each of the first 2 items of Result3 
IEnumerable<string> selCarPostsArrWithC = new string[]{}; 
IEnumerable<string> s2 = new string[]{}; 
foreach (var type in selectedDtTypeCars) 
{ 
    selCarPostsArrWithC = s1.Select(s => s.Insert(2, type));//C.WindDirNearMainGate C.WindDirNearMP5WestGate in FIRST iteration and so on 
    s2 = s2.Concat(selCarPostsArrWithC);// as soon as the SECOND iteration starts, the previous s2 list is overwritten with the subsequent result in selCarPostsArrWithC 
} 

Проблема здесь заключается в том, что во время отладки кода, я заметил, что как только я нажимаю клавишу F10 сразу после Еогеасп линии до фактически достигнув блока foreach, предыдущие значения в s2 уже перезаписаны с последующим результатом в selCarPostsArrWithC. Разъяснение ниже

Для первой итерации s2 имеет результат.

[0] "C.WindDirNearMainGate" 
[1] "C.WindDirNearMP5WestGate" 

В начале второй итерации перед входом внутри блока Еогеасп

s2 уже сбрасывает новые значения с WindVel некоторые, как:

[0] "C.WindVelNearMainGate" 
[1] "C.WindVelNearMP5WestGate" 

Пожалуйста, может любой помочь, что я Я делаю неправильно? Как я могу выполнить Result3 полужирным шрифтом, для списка IEnumerable?

ответ

0

В основном у вас есть список префиксов и список суффиксов. (Примечание: я снял код, и я не смог найти, где вы получили C., который был добавлен к каждому из значений.)

Для каждого префикса вам нужен суффикс.

Это использование SelectMany()

Я упростил свой код, потому что вы дали совсем немного кода. Но вот что я придумал:

var location = new[] 
    { 
     "NearMainGate", 
     "NearMP5WestGate" 
    }; 

    var modifier = new[] 
    { 
     "WindDir", 
     "WindVel" 
    }; 

    var lambdaResult = modifier.SelectMany(s => location.Select(l => string.Format("{0}{1}{2}", "C.", s, l))); 

    var queryResult = 
     from m in modifier 
     from l in location 
     select string.Format("{0}{1}{2}", "C.", m, l); 

Обратите внимание, что есть два решения: синтаксис запросов LINQ, и синтаксис LINQ лямбда.

В этой ситуации, я думаю, синтаксис запроса чище и проще для чтения, но для каждого из них.

А вот скрипка с доказательством функциональности: https://dotnetfiddle.net/Z61RsI

+0

Hi Cameron! wow Это было потрясающе. Большое спасибо. (Upvote требует 15 баллов, сейчас всего 7, как только я доберусь до 15, я это сделаю) Теперь я понимаю, как я новый, чтобы LINQ .. нужно узнать больше синтаксиса LINQ в дополнение к овладению C# , (возможно, вы уже поняли, что я совсем новая пчела) ;-) и ваши результаты лямбды и запроса работают как шарм. Не могли бы вы предложить хорошие книги, ресурсы для программирования LINQ и Winforms на C#? извините offtopic. – Nish

+0

@Nish Есть ** тонны ** ресурсов. Я лично лучше всего разбираюсь в рабочем коде. [Ресурсы Linq для MSDN] (https://msdn.microsoft.com/en-us/library/bb397926.aspx) велики. Если вы хотите использовать образцы кода, Microsoft имеет [101 LInq Samples] (https: // code. msdn.microsoft.com/101-LINQ-Samples-3fb9811b), чтобы посмотреть. – Cameron

+0

Спасибо Камерон. Имеет смысл. Да! Хороший день – Nish

1

Enumerable.Select ничего важного не делать, когда вы называете это, это просто устанавливает вещи так, что запрашиваемая работа будет выполнена позже по желанию.

Так что, когда вы пишете

selCarPostsArrWithC = s1.Select(s => s.Insert(2, type)); 

это не вызывает string.Insert еще. string.Insert вызывается только тогда, когда вы (или ваш отладчик) позже запускаете итерацию более selCarPostsArrWithC.

Как правило, это не имеет значения, кроме производительности, если вы перебираете перечислимое несколько раз. Однако здесь, поскольку string.Insert вызывается позже, чем вы ожидаете, аргументы, которые вы передаете ему, - , также оцениваются позже, чем вы ожидаете. У вас есть только одна переменная type, и эта переменная уже имеет следующее значение к моменту ее чтения.

В общем, вы можете решить эту проблему, создав новую переменную каждой итерации, который фиксирует значение type, как видно во время этой итерации:

foreach (var type in selectedDtTypeCars) 
{ 
    var type_ = type; 
    selCarPostsArrWithC = s1.Select(s => s.Insert(2, type_)); 
    s2 = s2.Concat(selCarPostsArrWithC); 
} 

(В настоящее время, C# уже делает это за кулисами foreach, но вам может понадобиться, чтобы написать ее, как это, если использует устаревший компилятор)

Или, наоборот, выполнять все оценки непосредственно в теле цикла:.

foreach (var type in selectedDtTypeCars) 
{ 
    selCarPostsArrWithC = s1.Select(s => s.Insert(2, type)).ToList(); 
    s2 = s2.Concat(selCarPostsArrWithC); 
} 

Хотя в этом случае было бы лучше всего сделать s2 a List<string> и вызвать его метод AddRange.

+0

Hi hvd. Спасибо за информацию .. Я пробовал форму решения Cameron .. и это сработало. Но спасибо еще. ваш комментарий отвечает, почему мой код не работает. много материала LINQ, чтобы узнать :-). – Nish

Смежные вопросы