简体   繁体   English

从文本文件解析字符串并使用LINQ

[英]Parsing a string from a textfile and using LINQ

I have a textfile which stores on each line a list of int arrays of the size 2. Each array is seperated by ';' 我有一个文本文件,该文件在每一行上存储一个大小为2的int数组的列表。每个数组用';'分隔';' and the int are seperated by ',' . 和int用','分隔。 The ints represent coordinates. 整数表示坐标。 For example what you may see on a line is 例如,您可能在一行上看到的是

1,0;5,9;3,2;6,7

of which the array of coordinates would be [1,0], [5,9], [3,2], [6,7] (int[2]). 其中坐标数组为[1,0], [5,9], [3,2], [6,7] (int [2])。 This would be put inside a list [[1,0], [5,9], [3,2], [6,7]] . 这将放在列表[[1,0], [5,9], [3,2], [6,7]] Then this list would be added to another list [[[1,0], [5,9], [3,2], [6,7]], [[a,b], [c,d], [e,f], [g,h]], [[i,j], [k,l], [m,n], [o,p]]] (Sorry if the representation is a bit dodgy). 然后,此列表将添加到另一个列表[[[1,0], [5,9], [3,2], [6,7]], [[a,b], [c,d], [e,f], [g,h]], [[i,j], [k,l], [m,n], [o,p]]] (很抱歉,如果表示有点狡猾)。 What I would like help with is parsing 我想帮忙的是解析

1,0;5,9;3,2;6,7

to add to a list which is List<List<int[]>> so a data structure which stores n amount of sets of n amount of integer coordinates. 要添加到List<List<int[]>>的列表中,则该数据结构将存储n个整数坐标的n个集合。 I have gathered I need to use parsing and possibly LINQ. 我已经收集到了我需要使用解析和LINQ的信息。

public class FileHandler : MonoBehaviour {

    string tileDataFile = "TileData.txt";
    List<List<int[]>> tileData = new List<List<int[]>>;
    bool FileExists()
    {
        if (File.Exists(tileDataFile))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    void GetFileData()
    {
        if (FileExists())
        {
            StreamReader SR = new StreamReader(tileDataFile, Encoding.Default);
            using (SR)
            {
                do
                {
                    tileData.Add(SR.ReadLine().Split(';').Where())                    
                }
            }
        }
    }

}

I have had a bit of experience using LINQ but I am not competent to a level where I can tackle this. 我在使用LINQ方面有一些经验,但是我没有能力解决这个问题。 Can anyone suggest a solution? 谁能提出解决方案? I hope I explained well enough. 我希望我解释得足够好。

Just apply the split until you brake the line to something that can be used to build a List of int arrays. 只需应用拆分,直到将行制动到可用于构建int数组列表的内容上即可。

var result = new List<int[]>();
foreach(var line in lines)
{
   var itemsForArray = line.Split(';');
   foreach(var intItems in itemsForArray)
   {
      var intItemsSplitted = intItems.Split(',');
      var firstValue = int.Parse(intItemsSplitted[0]);
      var secondValue = int.Parse(intItemsSplitted[1]);

      result.Add(new int[]{firstValue, secondValue});
   }
}


The LINQ approach (query): LINQ方法(查询):

var text = "1,2;2,2;1,4;0,1";
var result = (from t in text.Split(';')
              let s = t.Split(',')
              select new int[]    
              { 
                  int.Parse(s[0]),    
                  int.Parse(s[1]) 
              }).ToList();

If you prefer method syntax: 如果您更喜欢方法语法:

var result = text.Split(';')
    .Select(i => new int[]
    {
        int.Parse(i.Split(',')[0]),
        int.Parse(i.Split(',')[1])
    }).ToList();

I did not perform any checks, so they should be inserted there for code to be safe 我没有执行任何检查,因此为了安全起见,应该将它们插入其中

ok since you have full control of data format, then it is easier to serialize/deserialize your List> directly without the need to parse it yourself, you have several serialization options, there Newton.Json and you can serialize it to Json text, another option is to serialize it to Binary using BinaryFormatter .NET class and last you can use .NET XMLSerializer. 好的,因为您可以完全控制数据格式,所以直接序列化/反序列化List>而不需要自己解析就容易了,您有几个序列化选项,在Newton.Json中,您可以将其序列化为Json文本,另一个选项是使用BinaryFormatter .NET类将其序列化为Binary,最后可以使用.NET XMLSerializer。

usage for all of them is straight forward, as an example, if you chose Newton Json converter, you download Nuget package and then call it like this: 例如,如果选择了Newton Json转换器,则下载所有Nuget程序包,然后按以下方式调用它们:

string serializedObject = JsonConvert.SerializeObject(YourList);

then you save this string to a text file. 然后将此字符串保存到文本文件。

now to retrieve it, you do something like this,read the textfile that has the serialized list and place it in a string then: 现在要检索它,您可以执行以下操作,读取具有序列化列表的文本文件,并将其放入字符串中,然后:

 List<List<int[]>> myList= JsonConvert.DeserializeObject<List<List<int[]>>(serializedObject);

if you decide to use binary, here is MSDN article: 如果您决定使用二进制文件,则这里是MSDN文章:

https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.110).aspx

I assume the performance of this will not be all that great, and to be honest I would normally prefer to use json to do this, but here is a one liner linq that does what you want. 我认为它的性能不会那么好,老实说,我通常更喜欢使用json来做到这一点,但是这里有一个liner linq可以满足您的要求。 Also absolutely no safety if one of the values is not an integer. 如果其中一个值不是整数,也绝对没有安全性。

var line = "1,0;5,9;3,2;6,7";
            var list = line.Split(';').Select(a => a.Split(',').Select(b => int.Parse(b)).ToArray());
            foreach(var item in list){
                Console.WriteLine("a:" + item[0] + ", b:" + item[1]);
            }

If you want to do it in one expression, you could use this: 如果要在一个表达式中执行此操作,则可以使用以下命令:

Regex.Split( input, Regex.Escape( Environment.NewLine ) )
.Select( x => 
    x.Split( ';' ).Select( y =>
        y.Split( ',' )
        .Select( Int32.Parse )
        .ToList() )
    .ToList() )
.ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM