Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用helper类解析文本文件_C#_.net_Linq - Fatal编程技术网

C# 使用helper类解析文本文件

C# 使用helper类解析文本文件,c#,.net,linq,C#,.net,Linq,我有一个文本文件,其中包含电影名称及其部分的列表,如下所示: xxx, Author1, v6 the net, author1, v7 xxx, author3, v10 DDLJ, author3, v11 the fire, author5, v6 the health, author1, v8 the health, author7, v2 the hero, author9, v11 the hero, author8, v3 我想得到电影名称的最新版本。在这种情况下,它应该返回“D

我有一个文本文件,其中包含电影名称及其部分的列表,如下所示:

xxx, Author1, v6
the net, author1, v7
xxx, author3, v10
DDLJ, author3, v11
the fire, author5, v6
the health, author1, v8
the health, author7, v2
the hero, author9, v11
the hero, author8, v3
我想得到电影名称的最新版本。在这种情况下,它应该返回“DDLJ”和“the hero”

这就是我尝试过的:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace ProgramNamespace
{
    public class Program
    {
        public static List<String> processData(IEnumerable<string> lines)
        {           
            Dictionary<string, int> keyValuePairs = new Dictionary<string, int>();
            foreach (var item in lines)
            {
                string[] readsplitted = item.Split(',');              
                keyValuePairs.Add(readsplitted[0], Convert.ToInt32(
                    Regex.Replace(readsplitted[2], "[^0-9]+", string.Empty)));
            }

            //List<String> retVal = new List<String>();
            return retVal;
        }

        static void Main(string[] args)
        {
            try
            {
                List<String> retVal = processData(File.ReadAllLines(@"D:\input.txt"));
                File.WriteAllLines(@"D:\output.txt", retVal);
            }
            catch (IOException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用System.Text.RegularExpressions;
名称空间程序名称空间
{
公共课程
{
公共静态列表processData(IEnumerable行)
{           
Dictionary keyValuePairs=新字典();
foreach(行中的var项目)
{
字符串[]readsplitted=item.Split(',');
keyValuePairs.Add(readsplitted[0],Convert.ToInt32(
Regex.Replace(readsplitted[2],“[^0-9]+”,string.Empty));
}
//List retVal=新列表();
返回返回;
}
静态void Main(字符串[]参数)
{
尝试
{
List retVal=processData(File.ReadAllLines(@“D:\input.txt”);
writeAllines(@“D:\output.txt”,retVal);
}
捕获(IOEX异常)
{
控制台写入线(例如消息);
}
}
}
}
请注意,如果需要,我想添加一个助手类。

EDIT:version for replicated key 我重写了我给出的第一个解决方案,将重复数据考虑在内。诀窍是在键前添加一个递增数字,并用下划线分隔:这样每个键都是唯一的

例如,您的字典将按如下方式填写:

“1_xxx”,6
“2_网络”,7
“3_xxx”,10
“4_DDLJ”,11

然后在提供结果之前删除数字(和下划线)

public static List<String> processData(IEnumerable<string> lines)
{
    var keyValuePairs = new Dictionary<string, int>();

    int Position = 0;
    foreach (var item in lines)
    {
        Position++;
        string[] readsplitted = item.Split(',');
        keyValuePairs.Add(Position.ToString() +"_" + readsplitted[0], Convert.ToInt32(Regex.Replace(readsplitted[2], "[^0-9]+", string.Empty)));
    }
    var MaxVersion = keyValuePairs.Values.OrderByDescending(f => f).First();

    return keyValuePairs.Where(f => f.Value == MaxVersion).Select(f => string.Join("_", f.Key.Split('_').Skip(1))).ToList();
}
公共静态列表processData(IEnumerable行)
{
var keyValuePairs=新字典();
int位置=0;
foreach(行中的var项目)
{
位置++;
字符串[]readsplitted=item.Split(',');
添加(Position.ToString()+“”+readsplitted[0],Convert.ToInt32(Regex.Replace(readsplitted[2],“[^0-9]+”,string.Empty));
}
var MaxVersion=keyValuePairs.Values.OrderByDescending(f=>f.First();
返回keyValuePairs.Where(f=>f.Value==MaxVersion)。选择(f=>string.Join(“\”,f.Key.Split(“\”).Skip(1)).ToList();
}
详情如下:

  • keyValuePairs.Values
    将只返回版本号
  • .OrderByDescending(f=>f).First()
    将按降序对版本号进行排序,并选择第一个,即最高版本号
  • keyValuePairs。其中(f=>f.Value==MaxVersion)
    将选择与上面最高版本对应的键值对
  • 。选择(f=>f.Key)
    将为您提供
    词典的键,即标题

这样,您还可以保留您的
词典
;如果您只做了一次,并且不需要扩展代码或重用模型,那么就不必创建其他类或使其变得比需要的更复杂。

我就是这样做的。这说明了获取最大版本相同的所有电影名称的原因

public static List<String> processData(string fileName)
{
    var lines = File.ReadAllLines(fileName);

    var values = lines.Select(x => 
    {
        var readsplitted = x.Split(',');
        return new { Name = readsplitted[0], Verison = int.Parse(readsplitted[2].Replace("v", string.Empty))};  
    });

    var maxValue= values.Max(x => x.Verison);

    return values.Where(v => v.Verison == maxValue)
    .Select(v => v.Name)
    .ToList();  
}

static void Main(string[] args)
{
    try
    {
        List<String> retVal = processData(@"D:\output.txt");
    }
    catch (IOException ex)
    {
        Console.WriteLine(ex.Message);
    }
}
公共静态列表processData(字符串文件名)
{
var lines=File.ReadAllLines(文件名);
变量值=行。选择(x=>
{
var readsplitted=x.Split(',');
返回新的{Name=readsplitted[0],Verison=int.Parse(readsplitted[2].Replace(“v”,string.Empty));
});
var maxValue=values.Max(x=>x.Verison);
返回值。其中(v=>v.Verison==maxValue)
.选择(v=>v.Name)
.ToList();
}
静态void Main(字符串[]参数)
{
尝试
{
List retVal=processData(@“D:\output.txt”);
}
捕获(IOEX异常)
{
控制台写入线(例如消息);
}
}
  • 创建
    Movie
    类,以便为表示电影的每一行初始化对象。
  • 首先将传递给
    processData()
    的整个字符串按“,”的新行拆分
  • 提取每部电影的版本号(从“v”中提取),请参阅:
    extractNumberFromString()
    method
  • 找到最大版本号并获取(使用linq查询)所有共享最大版本号的电影

  • 公共静态列表processData(字符串s)
    {
    //列表以存储所有电影
    List allmovies=新列表();
    //先按新行拆分
    var splitbynewline=s.Split('\n');
    //按“,”拆分并初始化对象
    foreach(splitbynewline中的var行)
    {
    var moviestring=line.Split(',');
    //创建新的电影对象
    Movie obj=新电影{Name=moviestring[0],Author=moviestring[1],Version=moviestring[2]};
    obj.VersionNumber=extractNumberFromString(moviestring[2]);
    添加(obj);
    }
    //获取最大版本号
    double maxver=allmovies.Max(x=>x.VersionNumber);
    //设置并返回包含所有max版本电影的列表
    List result=allmovies.Where(x=>x.VersionNumber==maxver.ToList();
    返回结果;
    }
    /// 
    /// 
    ///将字符串中的数字转换为int32,例如sdfdf43gn将返回为43
    /// 
    ///包含在其内部作为数字的字符串
    ///int32
    公共静态双提取器numberfromstring(字符串值)
    {
    string returnVal=string.Empty;
    System.Text.RegularExpressions.MatchCollection集合=System.Text.RegularExpressions.Regex.Matches(值“\\d+”);
    foreach(集合中的System.Text.RegularExpressions.Match m)
    {
    returnVal+=m.ToString();
    }
    返回Convert.ToDouble(returnVal);
    }
    公映
    {
    公共字符串名称;
    公共字符串作者;
    公共字符串版本;
    公共双版本号;
    }
    
    对于这类任务,我通常更喜欢t
    public static List<Movie> processData(string s)
    {
        // list to store all movies
        List<Movie> allmovies = new List<Movie>();
    
        // first split by new line
        var splitbynewline = s.Split('\n');
        // split by ',' and initilize object
        foreach (var line in splitbynewline)
        {
            var moviestring = line.Split(',');
            // create new movie object
            Movie obj = new Movie { Name = moviestring[0], Author = moviestring[1], Version = moviestring[2] };
            obj.VersionNumber = extractNumberFromString(moviestring[2]);
            allmovies.Add(obj);
        }
    
        // get the max version number
        double maxver = allmovies.Max(x => x.VersionNumber);
        // set and returen list that containes all movies with max version
        List<Movie> result = allmovies.Where(x => x.VersionNumber == maxver).ToList();
    
        return result;
    }
    
    /// <summary>
    /// 
    /// convert number that exist in a string to an int32 for example sdfdf43gn will return as 43
    /// </summary>
    /// <param name="value">string that contains inside him as digits</param>
    /// <returns>int32</returns>
    public static double extractNumberFromString(string value)
    {
        string returnVal = string.Empty;
        System.Text.RegularExpressions.MatchCollection collection = System.Text.RegularExpressions.Regex.Matches(value, "\\d+");
        foreach (System.Text.RegularExpressions.Match m in collection)
        {
            returnVal += m.ToString();
        }
    
        return Convert.ToDouble(returnVal);
    }
    
    public class Movie
    {
        public string Name;
        public String Author;
        public string Version;
        public double VersionNumber;
    }
    
    public class MovieInfo
    {
        public string Name { get; set; }
        public string Author { get; set; }
        public int Version { get; set; }
    
        public static bool TryParse(string input, out MovieInfo result)
        {
            result = null;
            if (input == null) return false;
    
            var parts = input.Split(',');
            int version;
    
            if (parts.Length == 3 &&
                int.TryParse(parts[2].Trim().TrimStart('v'), out version))
            {
                result = new MovieInfo
                {
                    Name = parts[0],
                    Author = parts[1],
                    Version = version
                };
            }
    
            return result != null;
        }
    
        public override string ToString()
        {
            return $"{Name} (v{Version}) - {Author}";
        }
    }
    
    public static List<MovieInfo> processData(IEnumerable<string> lines)
    {
        if (lines == null) return null;
    
        var results = new List<MovieInfo>();
    
        foreach (var line in lines)
        {
            MovieInfo temp;
    
            if (MovieInfo.TryParse(line, out temp))
            {
                results.Add(temp);
            }
        }
    
        var maxVersion = results.Max(result => result.Version);
    
        return results.Where(result => result.Version == maxVersion).ToList();
    }
    
    private static void Main()
    {
        var lines = new List<string>
        {
            "xxx, Author1, v6",
            "the net, author1, v7",
            "xxx, author3, v10",
            "DDLJ, author3, v11",
            "the fire, author5, v6",
            "the health, author1, v8",
            "the health, author7, v2",
            "the hero, author9, v11",
            "the hero, author8, v3",
        };
    
        var processed = processData(lines);
    
        foreach (var movie in processed)
        {
            // Note: this uses the overridden ToString method. You could just do 'movie.Name'
            Console.WriteLine(movie);
        }
    
        GetKeyFromUser("\nDone!! Press any key to exit...");
    }