2015-05-16 3 views
-3

Как это сделать с LinQ?C# Linq Dictionary IO

У меня есть текстовый файл. (Его около 100 линий долго.)

6 7 
0/3 # ##t#kon tu#i#do#b#n ko#yk####a#s##ttak###lk##ul$$$$#$#$$$####$$$$#$$$$$$#$$#$$$$$#$ 

Я сохранил его в словарь (две линии).

alap = File.ReadAllLines("veetel.txt"); 
Dictionary<string,string> statisztikaDictionary = new Dictionary<string,string>(); 
for (int z = 1; z < alap.Length; z+=2) 
{ 
    statisztikaDictionary.Add(alap[z],alap[z-1]); 
} 

Первая строка, поэтому в этом 6-й день записи 7 является зарегистрированным пользователем песонов. Мне нужно создать статистику об этом так. Написать это так:

Day:Number of persons who made a record. 

Я насчитал поэтому количество людей и значение дня колеблется от 0-11, но мы «не» знаем это. Вторая строка начинается с 0/3, что означает 0 взрослых 3 детей. Мне нужно прочитать 2 значения в день и идентификатор и распечатать, сколько волка наблюдал человек (в этом случае 3). Я тренируюсь для своего выпускного экзамена, и я застрял в этом. Любая помощь была бы apriciated,

+0

Ваш вопрос неясна ... что такое * точная * проблема, с которой вы сталкиваетесь? – Sayse

+0

Я не знаю, как сделать День: номер с LinQ –

+0

Ну, как бы вы это сделали без Linq? что вы пробовали/исследовали? – Sayse

ответ

2

Я хотел бы предложить, чтобы создать пользовательский класс, который может содержать данные, относящиеся к/магазин. Пусть это будет Statisztika со следующими полями/свойствами: Day, PersonId, Visitor и CountOfVisits.

Statisztika определение класса:

public class Statisztika 
{ 
    private int iday = 0; 
    private int ipersonid = 0; 
    private int ivisitor =0; 
    private int icount =0; 

    //class constructor 
    public Statisztika(string[] twolines) 
    { 
     iday = Convert.ToInt32(twolines[0].Split(' ')[0]); 
     ipersonid = Convert.ToInt32(twolines[0].Split(' ')[1]); 
     //we have to replace these lines: 
     //ivisitor = Convert.ToInt32(twolines[1].Split('/')[0]); 
     //icount = Convert.ToInt32(twolines[1].Split('/')[1].Split(' ')[0]); 
     //with: 
     //check for single slash 
     int pos = twolines[1].IndexOf("/"); 
     if (pos>-1) 
     { 
      //in case of error TryParse method returns zero 
      Int32.TryParse(twolines[1].Substring(0,pos) 
       .Replace("#", "").Trim(), out ivisitor); 
      Int32.TryParse(twolines[1].Substring(pos+1,2) 
       .Replace("#","").Trim(), out icount); 
     } 
    } 

    public int Day 
    { 
     get {return iday;} 
     set {iday = value;} 
    } 

    public int PersonId 
    { 
     get {return ipersonid;} 
     set {ipersonid = value;} 
    } 

    public int Visitor 
    { 
     get {return ivisitor;} 
     set {ivisitor = value;} 
    } 

    public int CountOfVisits 
    { 
     get {return icount;} 
     set {icount = value;} 
    } 
} 

Как вы можете видеть, чтобы создать Statisztika объект, вам нужно передать две строки текста (из файла), чтобы иметь возможность инициировать поля. Теперь нам нужно создать List<Statisztika>. Представьте себе, что это контейнер данных. Чтобы получить данные из этого списка, мы можем использовать запрос Linq.

Использование:

string sFileName = @"D:\veetel.txt"; 
string[] alap = File.ReadAllLines(sFileName); 

List<Statisztika> stat = new List<Statisztika>(); 
for(int i=0; i<alap.Length; i+=2) 
{ 
    //Linq rules! 
    string[] twolines = alap.Skip(i).Take(2).ToArray(); 
    //create new Statisztika object and add to list 
    stat.Add(new Statisztika(twolines)); 
} 

//use create linq query, group data by day and visitor type ;) 
var qry = stat 
    .GroupBy(p=>new{p.Day, p.Visitor}) 
    .Select(grp=>new 
      { 
       Day = grp.Key.Day, 
       Visitor = grp.Key.Visitor, 
       SumOfVisits = grp.Sum(p=>p.CountOfVisits) 
      }) 
    .OrderBy(a=>a.Day) 
    .ThenBy(a=>a.Visitor); 

Console.WriteLine("Day Visitor SumOfVisits"); 
foreach(var sta in qry) 
{ 
    Console.WriteLine("{0}\t{1}\t{2}", sta.Day, sta.Visitor, sta.SumOfVisits); 
} 

Пример вывода:

Day Visitor SumOfVisits 
1 0 0 
2 0 0 
2 1 0 
3 0 0 
3 2 15 
4 0 0 
5 0 0 
6 0 12 
7 0 9 
7 1 9 
8 0 0 
9 0 0 
9 1 0 
10 0 0 
11 0 0 
11 1 0 
11 3 0 
11 13 0 

[EDIT]

Примечание: Если \ (слэш) не существует, Statisztika конструктор класса использует нули в Visitor и CountOfVisits полей/членов.

Если вы хотите, чтобы проверить, если код работает правильно, используйте этот код:

string sFileName = @"D:\veetel.txt"; 
    string[] alap = File.ReadAllLines(sFileName); 
    for(int i=0; i<alap.Length; i+=2) 
    { 
     int one = 0; 
     int two = 0; 
     string[] twolines = alap.Skip(i).Take(2).ToArray(); 
     int pos = twolines[1].IndexOf("/"); 
     if(pos>-1) 
     { 
      Int32.TryParse(twolines[1].Substring(0,pos) 
        .Replace("#", "").Trim(), out one); 
      Int32.TryParse(twolines[1].Substring(pos+1,2) 
        .Replace("#","").Trim(), out two); 
     } 
     Console.WriteLine("{0}\t{1}\t{2}", 
         twolines[1].Substring(0,8), one, two); 
    } 

Приведенный выше код производит вывод следующим образом:

#abor# # 0 0 
ta###t## 0 0 
0/# a #a 0 0 
a pat#k# 0 0 
e#zakrol 0 0 
1/3#sot# 1 3 
0/# a pa 0 0 
#3/0#s#t 3 0 
verofe#y 0 0 
ta#o#t#v 0 0 
eszakro# 0 0 
#/3#so## 0 3 
...etc. 

Cheers, Maciej

+0

Спасибо, что нашли время, помогая мне. Хотя это дает формат excition: ivisitor = Convert.ToInt32 (twolines [1] .Split ('/') [0]); –

+0

Интересно ... Я скопировал данные примера, предоставленные вами. У меня нет никаких исключений ... Вторая строка начинается с '0/3'? –

+0

http://pastebin.com/YUUrjHSd –

2

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

Чтобы иметь возможность запрашивать словарь для количества людей, которые регистрировали наблюдения в определенный день, и запрашивать количество волков, наблюдаемых человеком в определенный день, я бы создал словарь с ключом, составленным днем и personId и значение в качестве данных наблюдений.

См. Ниже пример 2 классов для хранения ключей и значений для вашего словаря.

Для ключей:

public class ObservationId 
{ 
    public int Day; 
    public int PersonId; 

    public ObservationId(int day, int personId) 
    { 
     this.Day = day; 
     this.PersonId = personId; 
    } 
    public ObservationId(string line) 
    { 
     // Add code here to split data in the line to fill day and personId values 
    } 
} 

Для значений:

public class ObservationData 
{ 
    public int Adults; 
    public int Childs; 
    public int TotalWolves 
    { 
     get { return this.Adults + this.Childs; } 
    } 
    public ObservationData(int adults, int childs) 
    { 
     this.Adults = adults; 
     this.Childs = childs; 
    } 
    public ObservationData(string line) 
    { 
     // Add code here to split data in the line to fill values for adults and childs (and optionally the rest of data) 
    } 
} 

Для заполнения данных из файла:

 string[] alap; 
     alap = File.ReadAllLines("veetel.txt"); 
     Dictionary<ObservationId, ObservationData> statisztikaDictionary = new Dictionary<ObservationId, ObservationData>(); 
     for (int z = 1; z < alap.Length; z += 2) 
     { 
      ObservationId id = new ObservationId(alap[z - 1]); 
      ObservationData data = new ObservationData(alap[z]); 
      statisztikaDictionary.Add(id, data); 
     } 

Для поиска днем ​​и человека ID:

public int GetTotalWolves(int day, int personId) 
    { 
     ObservationId id = new ObservationId(day, personId); 
     if (statisztikaDictionary.ContainsKey(id)) 
     { 
      return statisztikaDictionary[id].TotalWolves; 
     } 
     else 
     { 
      return 0; 
     } 
    } 

Для поиска в течение дня (с помощью Linq):

public int GetObservationsByDay(int day) 
    { 
     return statisztikaDictionary.Where(o => o.Key.Day == day).Count(); 
    } 
+0

Большое спасибо. Я утверждаю, что вы нашли время, помогая мне. –

+0

Да, это ценный ответ (upvoted). Взгляните на мой;) –

+0

Это как-то дает ошибку, что statisztikaDictionary является чистой, но это так, я не знаю, почему. Это дает ошибку в двух методах. –