C# Linq Dictionary IO
本文关键字:IO Dictionary Linq | 更新日期: 2023-09-27 17:49:33
我怎么用LinQ做到这一点?
我有一个txt文件。(大约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个值和一个ID,并打印出这个人观察到多少只狼(在本例中是3只)。我正在为期末考试做准备,结果被这个卡住了。
我建议创建可以保存/存储相关数据的自定义类。设为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
[编辑]
注意:如果'
(斜杠)不存在,Statisztika
类的构造函数在Visitor
和CountOfVisits
字段/成员中使用0。
如果您想检查代码是否正常工作,请使用以下代码:
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.
欢呼,Maciej
我猜你更喜欢一些指导,而不是一个工作代码作为完整的解决方案。
为了能够在字典中查询某天记录观察的人数,以及查询某个人在某天观察到的狼的数量,我将创建一个字典,该字典的键由day和personId组成,value作为观察数据。
请看下面的例子,有两个类用来保存字典的键和值。
密钥: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();
}