C# Linq 字典 IO
C# Linq Dictionary IO
如何使用 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 是记录的人员 ID。
我需要创建一个关于它的统计数据。
像这样写出来:
Day:Number of persons who made a record.
我数了一下,所以人数和日期值在 0-11 之间变化,但我们 "don't" 知道这一点。
第二行以 0/3 开头,表示 0 成人 3 儿童。我需要每天读取 2 个值和一个 ID,并打印出该人观察到的狼数量(在本例中为 3)。
我正在为期末考试进行培训,但我被困住了。任何帮助都会得到帮助,
我猜你更喜欢一些指导而不是工作代码作为完整的解决方案。
为了能够在字典中查询某一天记录观察的人数,并查询某个人在某一天观察到的狼的数量,我将创建一个字典,其键由以下组成day 和 personId 和 value 作为观察数据。
请参阅下面的示例,其中 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();
}
我建议创建可以 hold/store 相关数据的自定义 class。让它成为 Statisztika
和以下 fields/properties:Day
、PersonId
、Visitor
和 CountOfVisits
。
Statisztika
class 定义:
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
class 构造函数在 Visitor
和 CountOfVisits
fields/members 中使用零.
如果您想检查代码是否正常工作,请使用此代码:
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
如何使用 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 是记录的人员 ID。 我需要创建一个关于它的统计数据。 像这样写出来:
Day:Number of persons who made a record.
我数了一下,所以人数和日期值在 0-11 之间变化,但我们 "don't" 知道这一点。 第二行以 0/3 开头,表示 0 成人 3 儿童。我需要每天读取 2 个值和一个 ID,并打印出该人观察到的狼数量(在本例中为 3)。 我正在为期末考试进行培训,但我被困住了。任何帮助都会得到帮助,
我猜你更喜欢一些指导而不是工作代码作为完整的解决方案。
为了能够在字典中查询某一天记录观察的人数,并查询某个人在某一天观察到的狼的数量,我将创建一个字典,其键由以下组成day 和 personId 和 value 作为观察数据。
请参阅下面的示例,其中 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();
}
我建议创建可以 hold/store 相关数据的自定义 class。让它成为 Statisztika
和以下 fields/properties:Day
、PersonId
、Visitor
和 CountOfVisits
。
Statisztika
class 定义:
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
class 构造函数在 Visitor
和 CountOfVisits
fields/members 中使用零.
如果您想检查代码是否正常工作,请使用此代码:
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