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只)。我正在为期末考试做准备,结果被这个卡住了。

C# Linq Dictionary IO

我建议创建可以保存/存储相关数据的自定义类。设为Statisztika,具有以下字段/属性:Day, PersonId, VisitorCountOfVisits

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类的构造函数在VisitorCountOfVisits字段/成员中使用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();
    }