2014-12-08 2 views
1

У меня есть следующий словарь:итерация ряда словарных элементов

Dictionary<string, List<string>> myList = new Dictionary<string,List<string>>(); 

Этот словарь получает, я никогда не буду знать, сколько элементов у меня будет.

Пример вывода: элементы словаря: (ключ, значение)

{"Code",{"Test1", "Test2", "Test3"}} 

{"Desc",{"Desc1", "Desc2", "Desc3"}} 

{"Name",{"name1", "name2", "name3"}} 

Как я могу Переберите каждого словаря и получить значение т.е. по индексу

что-то, что дало бы - >

{Code = "Test1", Desc = "desc", Name = "name1"} 
{Code = "Test2", Desc = "desc2", Name = "name2"} 
{Code = "Test3", Desc = "desc3", Name = "name3"} 

Любые идеи?

Благодаря

+1

Как вы карту переписывался имя и предмет? – Sajeetharan

+0

Зачем использовать кортеж? Каково использование первого параметра, если он всегда дублирует значение из словаря? –

+0

У меня есть класс, который тоже соответствует. Кортеж был чем-то, что я пытался, раньше у меня был список строк. Это можно изменить. – tau

ответ

1

Ключ для построения набора матриц для каждого столбца данных, а не для каждой строки, как словарь перечислителем предоставит вам. Этого можно достичь с помощью метода расширения Aggregate и простого оператора Select.

// Assuming the following class as a destination type 
class Foo 
{ 
    public Foo(string[] values) 
    { 
     Code = values[0]; 
     Name = values[1]; 
     Desc = values[2]; 
    } 

    public string Code; 
    public string Name; 
    public string Desc; 
} 

// This would be the code required to parse the data 
var destination = dataSource["Code"].Aggregate(new List<Foo>(), (entries, _) => 
{ 
    var curentRow = entries.Count(); 

    var entryData = dataSource.Select(property => property.Value[curentRow]).ToArray(); 

    entries.Add(new Foo(entryData)); 

    return entries; 
}); 

В этом случае мы используем Code свойства в качестве ключа, чтобы выяснить, сколько записей есть в источнике данных (словарный). Если в вашем словаре есть строки с отсутствующими значениями (меньше элементов, чем в строке «Код»), этот код будет терпеть неудачу, поскольку он предполагает, что во всех рядах одинаковое количество элементов.

В этом случае метод Aggregate действует как цикл for, предоставляя нам базовый счетчик с именем currentRow, который мы будем использовать позже для доступа к определенным записям в ваших данных. Этот счетчик - это количество записей, которые мы сохранили в List<Foo>. Он начинается с 0 и увеличивается каждый раз, когда мы добавляем новое значение в результирующий набор.

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

-1

выглядит как неправильная структура данных. Похоже, у вас есть набор объектов, каждый из которых имеет произвольный набор атрибутов. Вам нужно map<string,map<string,string>>

"item1"->code:'code1",desc:"desc1".... 
"item2"->code:'code2",desc:"desc2", color:"red", size:'42" 

......

0

Это базовое решение, которое отлично решает проблему. Я создал объект IEnumerable, чтобы вы могли увеличивать цикл foreach на «Code», «Desc», ....

После того, как вы получите строки (которые являются ключами словаря), вы можете перебирать список, который является значением каждой клавиши в словаре. Нижеприведенный код Записывает и подсчитывает все элементы в словаре и для каждого значения записывает все элементы в списки.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     public static IEnumerable<string> Helper() // Neccessary to use in foreach loop 
     { 
      yield return "Code"; 
      yield return "Desc"; 
      yield break; 
     } 
     static void Main(string[] args) 
     { 
      Dictionary<string, List<string>> container = new Dictionary<string, List<string>>(); 
      List<string> l1 = new List<string>(); 
      List<string> l2 = new List<string>(); 

      l1.Add("l1s1"); 
      l1.Add("l1s2"); 
      l1.Add("l1s3"); 

      l2.Add("l2s1"); 
      l2.Add("l2s2"); 
      l2.Add("l2s3"); 

      container.Add("Code", l1); 
      container.Add("Desc", l2); 

      int count = 0; 
      foreach (string k in Helper()) // get all Keys 
      { 
       for (int i = 0; i < container[k].Count; i++) 
       { 
        Console.WriteLine(container[k][i].ToString()); // Write each element in list 
        count++; 
       } 
       Console.WriteLine(); 
      } 
      Console.WriteLine(count.ToString()); 
     } 
    } 
} 

Обратите внимание, что вам не нужно знать, сколько элементов будет в каждом списке.Выход, как:

enter image description here

Или без создания Helper() вы можете сделать, как показано ниже:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Dictionary<string, List<string>> container = new Dictionary<string, List<string>>(); 
      List<string> l1 = new List<string>(); 
      List<string> l2 = new List<string>(); 

      l1.Add("l1s1"); 
      l1.Add("l1s2"); 
      l1.Add("l1s3"); 

      l2.Add("l2s1"); 
      l2.Add("l2s2"); 
      l2.Add("l2s3"); 

      container.Add("Code", l1); 
      container.Add("Desc", l2); 

      int count = 0; 
      foreach (string k in new string [] {"Code","Desc"}) // get all Keys 
      { 
       for (int i = 0; i < container[k].Count; i++) 
       { 
        Console.WriteLine(container[k][i].ToString()); // Write each element in list 
        count++; 
       } 
       Console.WriteLine(); 
      } 
      Console.WriteLine(count.ToString()); 
     } 
    } 
} 
+1

Это довольно странное использование 'yield'. Вы можете просто сделать foreach (string k в new [] {"Code", "Desc"}) 'вместо всего этого. – Blorgbeard

+0

Правильно. Спасибо за уведомление. –

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