2013-04-11 4 views
1

У меня есть список строк, разделенных точкой с запятой.Правильный способ повторить это?

Там всегда будет четное число, потому что первый ключ, следующий значение,

например:

name;Milo;site;stackoverflow; 

Так что я разделить их:

var strList = settings.Split(';').ToList(); 

Но теперь я хотел бы использовать петлю foreach, чтобы поместить их в List<ListItem>

мне интересно, если это может быть сделано с помощью итерации, или если я должен использовать значение 'i' получить [i] and [i+1]

+0

Почему -1? Спасибо – jmasterx

+0

Я думаю, вы можете легко использовать LINQ для этой цели. Я больше не программирую на C#, поэтому не помню точный синтаксис, но я уверен, что это просто с LINQ в C# – Ehsan

+0

. Вы планируете переместить эту логику на метод утилиты, поэтому деталь реализации (Linq, foreach, для, Сплит, что угодно) не имеет значения и тривиальна, не так ли? –

ответ

1

Во-первых, ценную вспомогательную функцию я использую. Он похож на GroupBy, за исключением того, что он группируется по последовательному индексу, а не по другому.

public static IEnumerable<List<T>> GroupSequential<T>(this IEnumerable<T> source, int groupSize, bool includePartialGroups = true) 
    { 
     if (groupSize < 1) 
      throw new ArgumentOutOfRangeException("groupSize", groupSize, "Must have groupSize >= 1."); 
     var group = new List<T>(groupSize); 
     foreach (var item in source) 
     { 
      group.Add(item); 
      if (group.Count == groupSize) 
      { 
       yield return group; 
       group = new List<T>(groupSize); 
      } 
     } 
     if (group.Any() && (includePartialGroups || group.Count == groupSize)) 
      yield return group; 
    } 

Теперь вы можете просто сделать

var listItems = settings.Split(';') 
    .GroupSequential(2, false) 
    .Select(group => new ListItem { Key = group[0], Value = group[1] }) 
    .ToList(); 
+0

Кто бы это сделал? Шутки в сторону? –

+0

Не я. У morelinq есть метод [Batch] (https://code.google.com/p/morelinq/source/browse/MoreLinq/Batch.cs?r=f85495b139a19bce7df2be98ad88754ba8932a28). – I4V

+0

Их реализация на самом деле имеет недостаток. У них есть требуемый параметр resultSelector, а в теле методов они только называют «yield return ;», если '' является вызовом 'resultSelector'. Нет никаких оснований включать этот параметр. Если пользователь хочет преобразовать партии/группы, они могут просто вызвать '.Select (resultSelector)' сразу после вызова 'Batch'. –

3

Я не могу скомпилировать, но это должно работать для вас:

var list = new List<ListItem>(); 
for (int i = 0; i < strList.Count; i++) 
{ 
    i++; 
    var li = new ListItem(strList[i - 1], strList[i]); 
    list.Add(li); 
} 

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

Однако использование петли foreach по-прежнему потребует от вас знать немного больше об индексе, поэтому оно немного более прямолинейно с базовым циклом for.

+0

Спасибо, но дело было в том, чтобы избежать [i] – jmasterx

+1

@Milo, взгляните на решение внизу и обратите внимание, что он далеко не изящный с 'foreach'. Это была моя точка зрения. В приведенном ниже решении используется 'bool' to ***, выведите *** индекс. –

+1

лучше использовать [i] в ​​этом случае;) – Evgeny

1

, если вы хотите использовать Foreach

string key=string.Empty; 
    string value=string.Empty; 

    bool isStartsWithKey=true; 
    var strList = settings.Split(';').ToList() 

    foreach(var item in strList) 
    { 
     if(isStartsWithKey) 
     { 
     key=item; 
     } 
     else 
     { 
     value=item; 
     //TODO: now you can use key and value 
     } 

     isStartsWithKey=!isStartsWithKey; 
    } 
+1

+1 для решения с использованием 'foreach'. –

0
List<int, string> yourlist; 
for(int i=0;i<strList.length/2;i++) 
{ 
    yourlist.add(new ListItem(strList[i*2], strList[i*2+1])); 
} 
-1

это кажется мне быть Проще всего

for(var i = 0; i < strList.Count(); i = i + 2){ 
    var li = new listItem (strList[i], strList[i + 1]; 
    listToAdd.Add(li); 
} 

обновленный пример

for (var i = 0; i < strList.Count(); i = i + 2){ 

    if (strList.ContainsKey(i) && strList.ContainsKey(i + 1)){ 
     listToAdd.Add(new listItem(strList[i], strList[i + 1]); 
    } 
} 
+0

Цикл for не приведет к ошибке индекса за пределами границ. Итак, что происходит на первой итерации, var i устанавливается в 0, второй - в 2, потому что счетчик итераций i = i + 2, i

+0

@ KennethGarza это может быть, если количество элементов нечетное, но в соответствии с OP, которое не должно быть. – juharr

+0

Я понимаю, что вы говорите, но это простой пример. В реальности вы должны сделать проверку, чтобы увидеть, существует ли индекс, прежде чем пытаться получить к нему доступ. –

4

Это может быть сделано с LINQ, но я не уверен, что это один лучше

var dict = input.Split(';') 
      .Select((s, i) => new { s, i }) 
      .GroupBy(x => x.i/2) 
      .ToDictionary(x => x.First().s, x => x.Last().s); 

Вы также можете использовать moreLinq «s Batch для этого

var dict2 = input.Split(';') 
      .Batch(2) 
      .ToDictionary(x=>x.First(),x=>x.Last()); 
+0

+1 для решения рычага LINQ. –

+0

+1 для использования linq. – CSharpie

+0

+1, но это выглядит странно!) – Evgeny

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