C#Linq问题

时间:2011-04-28 23:37:22

标签: c# linq

我有一个文本文件,我在其中存储地址簿的条目。 布局如下:

名称:
联系方式:
产品:
数量:

我已经写了一些linq代码来获取名称加上接下来的四行,用于按名称搜索功能。 我也希望能够通过联系方式进行搜索。 挑战是匹配联系信息,抓住接下来的3行,并在比赛前抓住线路。 这样,如果使用“按联系人搜索”,将返回完整的信息列表。

  private void buttonSearch_Click(object sender, EventArgs e)
    {
            string[] lines = File.ReadAllLines("C:/AddressBook/Customers.txt");
            string name = textBoxSearchName.Text;
            string contact = textBoxContact.Text;

            if (name == "" && contact == "")
            {
                return;
            }

            var byName = from line in lines
                         where line.Contains(name)
                         select lines.SkipWhile(f => f != line).Take(4);

            //var byContact = from line in lines
            //                where line.Contains(name)
            //                select lines.SkipWhile(f => f != name).Take(4);


            if (name != "")
            {
                foreach (var item in byName)
                    foreach (var line in item) { listBox2.Items.Add(line); }

                listBox2.Items.Add("");
            }

            //if (contact != "")
            //{
            //    foreach (var item in byContact)
            //        foreach (var line in item) { listBox2.Items.Add(line); }

                //listBox2.Items.Add("");
            }
    }

4 个答案:

答案 0 :(得分:4)

首先,如果可以,我建议您更改数据存储方法。

其次我建议将文件读入一个对象,如下所示:

public class Contact
{

    public string Name {get; set;}
    public string Contact {get; set;}
    public string Product {get; set;}
    public int Quantity {get; set;}
}
...
public IEnumerable<Contact> GetContacts()
{
    //make this read line by line if it is big!
    string[] lines = File.ReadAllLines("C:/AddressBook/Customers.txt");
    for (int i=0;i<lines.length;i += 4)
    {
        //add error handling/validation!
        yield return new Contact()
        {
              Name = lines[i],
              Contact = lines[i+1],
              Product = lines[i+2],
              Quantity = int.Parse(lines[i+3]
         };
    }
}
private void buttonSearch_Click(object sender, EventArgs e)
{
    ...
    var results = from c in GetContacts()
                 where c.Name == name ||
                       c.Contact == contact
                 select c;
    ...
}

答案 1 :(得分:0)

看看这是否有用

 var contactLinesList = lines.Where(l => l.Contains(name))
                           .Select((l, i) => lines.Skip(i - 1).Take(4)).ToList();


 contactLinesList.ForEach(cl => listBox2.Items.Add(cl));

答案 2 :(得分:0)

如果你的文本文件足够小,我建议使用正则表达式。这正是它的设计目标。在我的头顶,表达式看起来像这样:

(?im)^Name:(.*?)$ ^Contact:search_term$^Product:(.*?)$^Quantity:(.*?)$

答案 3 :(得分:0)

这不是地球上最小的代码,但它展示了如何做一些事情。虽然我不建议使用它,因为它理解起来相当复杂。这被认为是一个业余爱好者,只是学习代码!我建议你在一个众所周知的结构中加载文件,并在那个 Linq 上...无论如何...这是一个 C# 控制台应用程序使用 Linq语法和一个扩展方法建议您执行的操作:

using System;
using System.Collections.Generic;
using System.Linq;
namespace stackoverflow.com_questions_5826306_c_linq_question
{
    public class Program
    {
        public static void Main()
        {
            string fileData = @"
Name: Name-1
Contact: Xpto
Product: Abc
Quantity: 12

Name: Name-2
Product: Xyz
Contact: Acme
Quantity: 16

Name: Name-3
Product: aammndh
Contact: YKAHHYTE
Quantity: 2
";
            string[] lines = fileData.Replace("\r\n", "\n").Split('\n');
            var result = Find(lines, "contact", "acme");
            foreach (var item in result)
                Console.WriteLine(item);
            Console.WriteLine("");
            Console.WriteLine("Press any key");
            Console.ReadKey();
        }

        private static string[] Find(string[] lines, string searchField, string searchValue)
        {
            var result = from h4 in
                             from g4 in
                                 from i in (0).To(lines.Length)
                                 select ((from l in lines select l).Skip(i).Take(4))
                             where !g4.Contains("")
                             select g4
                         where h4.Any(
                             x => x.Split(new char[] { ':' }, 2)[0].Equals(searchField, StringComparison.OrdinalIgnoreCase)
                                 && x.Split(new char[] { ':' }, 2)[1].Trim().Equals(searchValue, StringComparison.OrdinalIgnoreCase))
                         select h4;
            var list = result.FirstOrDefault();
            return list.ToArray();
        }
    }
    public static class NumberExtensions
    {
        public static IEnumerable<int> To(this int start, int end)
        {
            for (int it = start; it < end; it++)
                yield return it;
        }
    }
}