C # объект для списка c # - PullRequest
       9

C # объект для списка c #

0 голосов
/ 09 ноября 2018

Я читаю в CSV-файле, что я хотел бы добавить второй столбец в тот же список, что и столбец, который соответствует имени. Я проверяю, что следующая строка равна предыдущей записи, но затем я зацикливаю массив, находя совпадение, но я не уверен, как добавить этот internalList обратно в объект класса.

Есть ли лучший способ сделать это?

Программа

while ((s = sr.ReadLine()) != null)
{
string[] words = s.Split('\t');

if (previousrecord == words[0])
{
    for (int i = 0; i < ALEComName.Count; ++i)
        {

        }
}
else
{
    Name person = new Name();
    person.Name = words[0];
    List<SubName> internalList = new List<SubName>();
    SubName AssociatedSub = new SubName { Name = words[1] };
    internalList.Add(AssociatedSub);
    person.AssociatedSub = internalList;
    ALEComName.Add(Disease);
}
previousrecord = words[0];

Dto

    public class Name
    {

        public string Name { get; set; }

        public List<SubName> AssociatedSub { get; set; }
    }

    public class SubName
    {

        public string Name { get; set; }

    }
}

Файл CSV

A   A
B   B
C   A
C   B
C   C
D   A
D   B

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

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

class Program {
        static void Main(string[] args) {

            using(var file = new StreamReader(@"../file.csv")) {
                var dict = new Dictionary<string, List<string>>();
                List<string> split;
                string line, key;

                while((line = file.ReadLine()) != null) {
                    split = line.Select(l => new string(l, 1)).Where(l => l != " ").ToList();
                    key   = split[0];
                    split.RemoveAt(0);

                    if(dict.ContainsKey(key)) { 
                        dict.TryGetValue(key, out var values);
                        values.AddRange(split);
                    } else dict.Add(key, split);
                }

                foreach(KeyValuePair<string, List<string>> r in dict) {
                    foreach(var val in r.Value) {
                        Console.WriteLine("Main = {0}, Sub = {1}", r.Key, val);
                    }
                }
            }
        }
    }
0 голосов
/ 09 ноября 2018

Вы можете прочитать все строки, а затем использовать Linq:

var data = File.ReadAllLines(@"c:\temp\sample.txt");
var names = data.Select(d => d.Split('\t'))
.Select(s => new { Name = s[0], SubName = s[1] })
.GroupBy(o => o.Name)
.Select(g => new Name()
{
    Name1 = g.Key,
    AssociatedSub = g.Select(v => new SubName() { Name = v.SubName }).ToList()
});

//This part is just to show the output
foreach (var name in names)
{
    Console.WriteLine($"Name: {name.Name1}, AssociatedSub: {string.Join(",", name.AssociatedSub.Select(s => s.Name).ToArray())}");
}

Выход:

Имя: A, AssociatedSub: A

Имя: B, AssociatedSub: B

Имя: C, AssociatedSub: A, B, C

Имя: D, AssociatedSub: A, B

Мне пришлось изменить имя свойства на Name1, так как это недопустимая языковая конструкция.

Сначала вы выбираете результат разделения, затем создаете анонимный тип со свойствами Name и SubName, которые будут использоваться для группировки. Наконец, вы выбираете из сгруппированных результатов и создаете экземпляры.

Это просто быстрый пример, поэтому будьте осторожны с ошибками, такими как Split не возвращает ожидаемое количество деталей.

...