C# Linq question

  • 本文关键字:question Linq 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("");
            }
    }

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

其次,我建议将文件读入一个对象,就像这样:
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;
    ...
}

看看是否可以

 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));

这不是世界上最小的代码,但它展示了如何做一些事情。虽然我不推荐使用它,因为理解起来相当复杂。这是要考虑作为一个业余爱好者,只是学习代码!!我建议你将文件加载到一个已知的结构中,并对其执行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("rn", "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;
        }
    }
}

如果您的文本文件足够小,我建议使用正则表达式代替。这正是它的设计目的。在我的脑海中,表达式看起来像这样:

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

相关内容

  • 没有找到相关文章

最新更新