我想将字符串转换为对象。 该字符串使用以下语法。
string nameIdPair = "name1:123\r\nname2:456\r\n";
并说我想要转换它的对象定义如下。
public struct MyStruct
{
public string Name;
public int Id;
}
我想出了以下查询
var elements = nameIdPair.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)
.Where(p => !string.IsNullOrWhiteSpace(p))
.Select(r => r.Split(':'))
.Select(s => ReturnObject(s));
另外我更喜欢编写sql类型的linq查询,所以我想我会拆分上面的查询 并想出了以下解决方案
var elements = from p in nameIdPair.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)
where !string.IsNullOrWhiteSpace(p)
select ReturnObject(p); // Here p is string not string[]
我不想调用辅助函数: -
string[] tempContainer = new string[] { };
var elements = from p in nameIdPair.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)
where (tempContainer = p.Split(':')) != null
select new { name = tempContainer[0], id = tempContainer[1] };
private static object ReturnObject(string inputString)
{
string[] value = inputString.Split(':');
myObject.Name = value[0];
myObject.Id = int.Parse(value[1]);
return myObject;
}
注意在上一个查询中我使用了dummyContainer并且只调用Where()来加载 dummyContainer。 我想在不使用虚拟变量或外部的情况下重写最后一个查询 函数调用,但是我无法找到可行的解决方案。
我可以写下面的内容
var elements = from p in nameIdPair.Split(new string[] { "\r\n", "\n" },StringSplitOptions.RemoveEmptyEntries)
select new { name = p.Split(':')[0], id = p.Split(':')[1] };
但是我在这里一次又一次地对同一个字符串进行拆分操作,我该如何避免这种情况,
没有临时变量。
此外,我忘了这些称为{名称}的LINQ查询样式,而不是(from p in elements)
,而不是elements.Select()
。
此外,我想知道如何重写本帖子中的第一个查询,而无需调用
ReturnObject
功能
我进一步研究并找到let
var items = from p in nameIdPair.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)
let r = p.Split(':')
select new { name = r[0], id = r[1] };
谢谢:)
答案 0 :(得分:2)
您可以使用let
,如下所示:
var elements = from p in nameIdPair.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)
let arr = p.Split(':')
select new { name = arr[0], id = arr[1] };
如果您希望它返回MyStruct
而不是匿名类对象,请尝试以下操作:
var elements = from p in nameIdPair.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries)
let arr = p.Split(':')
select new MyStruct { Name = arr[0], Id = int.Parse(arr[1]) };
对于LINQ语法,我相信你的意思是流畅的vs查询表达式。
您可以在此处详细了解:LINQ - Fluent and Query Expression - Is there any benefit(s) of one over other?
答案 1 :(得分:0)
这是一个只调用Split一次的解决方案。您可以将其粘贴到LINQPad中进行尝试。 我不认为在LINQ中有一个等效的Unzip方法,但我很乐意另外学习。
此解决方案取决于没有空名称或ID条目。
void Main()
{
string nameIdPair = "name1:123\r\nname2:456\r\n";
var strings = nameIdPair.Split(new string[]{ "\r\n", "\r", ":" },
StringSplitOptions.RemoveEmptyEntries);
var structs = strings.Unzip();
structs.Dump();
}
public struct MyStruct
{
public string Name;
public int Id;
}
static class Helpers
{
public static IEnumerable<MyStruct> Unzip(this IEnumerable<string> items)
{
using(var en = items.GetEnumerator())
{
string name = null;
while(en.MoveNext())
{
if(name == null){
name = en.Current;
}
else{
int id = int.Parse(en.Current);
yield return new MyStruct{Name = name, Id = id};
name = null;
}
}
}
yield break;
}
}