从IEnumerable <t> </t>中提取文本

时间:2009-02-11 15:22:55

标签: linq

我有一个IEnumerable<T>集合,其中包含Name,FullName和Address。

地址如下:

Street1=54, Street2=redfer street, Pin=324234
Street1=54, Street2=fdgdgdfg street, Pin=45654
Street1=55, Street2=tryry street, Pin=65464

我想遍历此集合并仅打印那些名称为Street1 = 54

的FullNames

我如何在LINQ中执行此操作?

好的我能够这样做来提取地址的街道

coll.Address.Split(",".ToCharArray())[0]returns me Street1=54 . 

现在如何将其添加到条件中并仅打印那些名称为Street1 = 54

的FullName

6 个答案:

答案 0 :(得分:2)

根据您的更新,您可以通过以下方式调整Jared Par的代码:

var result = collection.Where(x => x.Address.Contains("Street1=54"));
foreach ( var cur in result ) {
  Console.WriteLine(string.Format("{0}, {1}", cur.Name, cur.FullName));
}

如果您希望能够使用变量插入Street1值,请执行以下操作:

var street1 = "54";
var result = collection.Where(x => x.Address.Contains("Street1=" + street1 ));
foreach ( var cur in result ) {
  Console.WriteLine(string.Format("{0}, {1}", cur.Name, cur.FullName));
}
顺便说一句,你真的应该更新你的问题或在特定答案中添加评论,而不是添加一个不是的新答案。

答案 1 :(得分:1)

试试这个

var result = collection.Where(x => x.Address.Street1==54);
foreach ( var cur in result ) {
  Console.WriteLine(var.Name);
}

答案 2 :(得分:0)

选择正确的列表:

IList<T> matches = myListOfEnumerables.Where(m => m.Street1 == 54).ToList();

然后循环并打印。

答案 3 :(得分:0)

实际上记录看起来像这样:

{Name="Jan" FullName="Kathy Jan" Address="Street1=54, Street2=redfer street, Pin=324234"}

我必须遍历此集合并仅打印那些名称为Street1 = 54

的FullNames

答案 4 :(得分:0)

如果更新的信息准确无误,您应该更改存储数据的方式。

看起来您已将地址信息打包成字符串。为什么不将它存储为对象。实际上,为什么不像Name和FullName在同一个对象中的更多字段呢? (以及为什么要复制名字信息?)

public class Person
{
    public string FirstName, LastName, Street1, Street2, Pin;
}

IEnumerable<Person> persons = GetAllPersonsSomehow();

foreach (Person person in persons.Where(p => p.Street1 == "54"))
    Console.WriteLine(person.LastName + ", " + person.FirstName);

假设您必须将地址信息保存在字符串中,您需要一个解析器。

public static IDictionary<string, string> GetAddressFields(string address)
{
    return address.Split(',').ToDictionary(
                s => s.Substring(0, s.IndexOf('=')).Trim(),
                s => s.Substring(s.IndexOf('=') + 1).Trim());
}


foreach (Person person in persons.Where(p => 
                GetAddressFields(p.Address)["Street1"] == "54")) 
    Console.WriteLine(person.LastName + ", " + person.FirstName);

答案 5 :(得分:0)

所以,你可以做的是你可以编写一个生成器来解析Address字段,然后枚举它的属性。这在函数式编程领域是相当普遍的事情。

公平地说,你会希望这个代码是懒惰的,因为它只会计算一个最小集合。我将从BCL建议一些代码,但你可以(并且可能应该)用生成器重写相同的辅助方法。

public static IEnumerable<KeyValuePair<string,string>> NameValueSplit( this string s )
{
    foreach (var x in s.Split(','))
    {
        var y = x.Split(new char[] { '=' }, 2, StringSplitOptions.None);
        yield return new KeyValuePair<string, string>(y[0].TrimStart(), y[1].TrimEnd());
    }
}

使用该辅助函数,您可以编写这样的代码

var result = collection.Where(x => x.Address
    .NameValueSplit().Any(x => x.Key == "Street1" && x.Value == "54"));
foreach ( var item in result ) 
{
    Console.WriteLine(item.Name);
}

现在,如果您正在考虑这个代码,则此代码将无法在您的SQL Server上运行,但您可以编写WHERE子句,在其中搜索地址字段以查找子字符串%Street1 = 54%。我喜欢对字符串操作进行惰性求值,并认为这是BCL中缺少的功能。这就是我提出这种解决方案的原因。