2011-03-01 64 views
0

我正在尝试构建linq表达式来解决我的问题。我有一个字符串解析字符串和解析值的顺序

List<string> arr = new List<string>(); 
arr.Add("<desc><ru>1</ru><en>3</en></desc>"); 
arr.Add("<desc><ru>2</ru><en>4</en></desc>"); 

我要分析每一个项目和订单的列表导致

fake sample: 
arr.Select(ParseItem("en")).OrderBy(x) 

然后我们在RU两个项目,以1,2

感谢所有和抱歉我的英文不好 感谢所有回复,但是如何将结果转换为IQueryable

class Test { public string data { get; set; } } 
List<Test> arr = new List<Test>(); 

arr.Add(new Test { data = "<desc><ru>AAA</ru><en>One</en></desc>" }); 
arr.Add(new Test { data = "<desc><ru>1</ru><en>Two</en></desc>" }); 
arr.Add(new Test { data = "<desc><ru>22</ru><en>Ab</en></desc>" }); 
IQueryable<Test> t = arr.AsQueryable(); 

// here the trouble how to convert to IQueryable<Test> 
t = t.Select(s => XElement.Parse(s.data)).Select(x => x.Element("en")). 
OrderBy(el => el.Value); 

再次感谢

+0

不清楚为什么你给出的代码会用'ru'做任何事情......或者你用你给出的表达式做什么(无论如何,就参数而言)是无效的。 – 2011-03-01 10:04:22

+0

你不能使用XML而不仅仅是裸露的字符串吗?它会根据'XDocument'开放很多可能性。 – Bazzz 2011-03-01 10:04:41

+0

@Jon Skeet感谢您的回应,我的输入参数是女士,我想对某些函数进行分析,然后得到之间的一部分字符串,以及在最后我想排序的所有结果... – 2011-03-01 10:07:41

回答

2

问题更新后 - 这将<en>节点值恢复您的订购数据:

var result = arr 
    .OrderBy(t=> 
     XElement.Parse(t.data).Element("en").Value 
    ); 

结果可修改为IOrderedEnumerable<Test>类型。

+0

嗨,谢谢,如何返回不临时项目,但原来的IQueryable t = arr.AsQueryable(); t = t.Select(s => XElement.Parse(s))。Select(x => x.Element(“en”))。OrderBy(el => el.Value); – 2011-03-01 10:32:20

+0

@Sanja Melnichuk:更新了我的答案 – Alex 2011-03-01 11:10:19

2

这将生成ru标记中的值的列表(假设它们是整数),按en标记中的值排序(再次假设为整数)。

List<string> items = arr.Select(s => XElement.Parse(s)) 
         .OrderBy(xml => (int)xml.Element("en")) 
         .Select(xml => (int)xml.Element("ru")) 
         .ToList(); 

如果你只是想一一列举,则可以省略ToList电话:

foreach (var item in arr.Select(s => XElement.Parse(s)) 
         .OrderBy(xml => (int)xml.Element("en")) 
         .Select(xml => (int)xml.Element("ru"))) 
{ 
    // do something with item 
} 
+0

谢谢你能读我的编辑问题 – 2011-03-01 10:49:26

1

我不知道我有例外的结果是什么,但如果你需要在en由值ru责令选择值,那么这就是:

var orderedItems = (
    from item in arr 
    let x = XElement.Parse(item) 
    let ruValue = (int)x.Element("ru") 
    let enValue = (int)x.Element("en") 
    orderby ruValue 
    select enValue 
    ).ToList(); 
0

我不知道它是否为时已晚,但如果你想分析文本,如果它是一个整数,然后按值排序,否则按文本排序,那么这可能会有所帮助。

您需要定义这样的功能,使分析在LINQ表达式:

Func<string, int?> tryParseInteger = text => 
{ 
    int? result = null; 
    int parsed; 
    if (int.TryParse(text, out parsed)) 
    { 
     result = parsed; 
    } 
    return result; 
}; 

然后,你可以做的查询是这样的:

var xs = new [] { "Hello", "3ff", "4.5", "5", }; 
var rs = 
    (from x in xs 
    select tryParseInteger(x)).ToArray(); 
// rs == new int?[] { null, null, null, 5, }; 

在你的情况,你可能想是这样的:

var elements = new [] 
{ 
    "<desc><ru>AAA</ru></desc>", 
    "<desc><ru>1</ru></desc>", 
    "<desc><ru>42</ru></desc>", 
    "<desc><ru>-7</ru></desc>", 
    "<desc><ru>BBB</ru></desc>", 
    "<desc><ru>22</ru></desc>", 
}; 

var query = 
    from e in elements 
    let xe = XElement.Parse(e) 
    let v = xe.Element("ru").Value 
    orderby v 
    orderby tryParseInteger(v) 
    select v; 

这将使你:

{ "AAA", "BBB", "-7", "1", "22", "42" } 

如果你想治疗非整数(即解析为空值)为零,然后使用该行更改查询:

orderby tryParseInteger(v) ?? 0 

然后你会得到这样的:

{ "-7", "AAA", "BBB", "1", "22", "42" } 

我希望这有助于。