C# 从大列表中提取过滤列表

C# 从大列表中提取过滤列表,c#,arrays,linq,C#,Arrays,Linq,我正在试图找到一种通过“File.ReadAllLines(“names.txt”);“请求获取过滤数组的快速方法,我有一个包含数千个名称的文本文件,基本上我只需要一个包含以下任何字符的名称列表,我用SQL查询这将是一个“选择”语句,添加了一些“或”条件,所以我的代码是这样的 var allowedChars = ["v","h","r"]; var allNames = File.ReadAllLines("names.txt"); 所以像“大卫”、“约翰”和“拉里”这样的名字是我所期望的

我正在试图找到一种通过“File.ReadAllLines(“names.txt”);“请求获取过滤数组的快速方法,我有一个包含数千个名称的文本文件,基本上我只需要一个包含以下任何字符的名称列表,我用SQL查询这将是一个“选择”语句,添加了一些“或”条件,所以我的代码是这样的

var allowedChars = ["v","h","r"];
var allNames = File.ReadAllLines("names.txt");
所以像“大卫”、“约翰”和“拉里”这样的名字是我所期望的 但是像“彼得”、“西蒙”和“保罗”这样的名字不包括在内

我知道我可以使用foreach来实现这一点,但我想知道是否有一些linq one liner可以实现这一点,而且“allowedChars”数组可能有不同的长度,任何帮助都会很好

var allowedNames = allNames.Where(n => allowedChars.Any(c => n.IndexOf(c) > -1));
虽然文件变得越来越大,但您可能需要考虑某种数据库解决方案,或者至少使用< /P>
var items = new List<string();
const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead(fileName))
  using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) {
    String line;
    while ((line = streamReader.ReadLine()) != null) 
      if (allowedChars.Any(c => line.IndexOf(c) > -1))
        items.Add(line);
  }
var items=新列表行。IndexOf(c)>-1))
项目。添加(行);
}
因此,您不会同时将它们全部加载到内存中

虽然文件变得越来越大,但您可能需要考虑某种数据库解决方案,或者至少使用< /P>
var items = new List<string();
const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead(fileName))
  using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) {
    String line;
    while ((line = streamReader.ReadLine()) != null) 
      if (allowedChars.Any(c => line.IndexOf(c) > -1))
        items.Add(line);
  }
var items=新列表行。IndexOf(c)>-1))
项目。添加(行);
}
因此,您不会同时将它们全部加载到内存中。

以下是一个示例:

var allowedChars = new char[] {'v','h','r'};
var allNames = new string[] { "peter", "paul", "victor", "hans" };

var names = allNames.Where(t => allowedChars.Any(c => t.Contains(c)));
下面是一个例子:

var allowedChars = new char[] {'v','h','r'};
var allNames = new string[] { "peter", "paul", "victor", "hans" };

var names = allNames.Where(t => allowedChars.Any(c => t.Contains(c)));

您应该使用
ReadLines
,而不是
ReadAllLines
,来流式传输数据,而不是强迫您将整个文件的内容读入内存。@Blorgbeard文件中只保留“几千个名称”。@Blorgbeard您永远不知道文件的增长速度。如果需要大量的数据来处理这些数据,你可以考虑不做,但是从字面上来说就像删除这五个字母一样简单。谢谢各位,我要用“Yuriy Faktorovich”的建议,看起来最漂亮。并且可以根据我的需要工作,再次感谢。@Servy true,但是您还必须注意,
allNames
现在是一个IEnumerable而不是数组,并且多次枚举将多次读取文件(除非我弄错了)。您应该使用
ReadLines
,而不是
ReadAllLines
,允许您以流式传输数据,而不是强制您将整个文件的内容读入内存。@但只保留文件中的“几千个名称”。@Blorgbeard您永远不知道文件的增长速度。如果需要大量的数据来处理这些数据,你可以考虑不做,但是从字面上来说就像删除这五个字母一样简单。谢谢各位,我要用“Yuriy Faktorovich”的建议,看起来最漂亮。并且可以根据我的需要工作,再次感谢。@Servy true,但是您还必须注意,
allNames
现在是一个IEnumerable而不是数组,并且多重枚举将多次读取文件(除非我弄错了)。与其添加所有额外的代码来尝试流式传输数据,您只需将
File.ReadLines
与标准LINQ解决方案一起使用即可。这样做将使数据流化,事实上允许结果流化(例如,通过
foreach
),而不是像您所做的那样,将过滤后的结果具体化到
列表中。@Servy我相信您是对的,这是更具可读性的解决方案。我在谷歌上搜索了读取文件行的最快方法,并找到了它。与其添加所有额外的代码来尝试流式传输数据,您只需将
file.ReadLines
与标准LINQ解决方案结合使用即可。这样做将使数据流化,事实上允许结果流化(例如,通过
foreach
),而不是像您所做的那样,将过滤后的结果具体化到
列表中。@Servy我相信您是对的,这是更具可读性的解决方案。我在谷歌上搜索了最快的读取文件行的方法,然后发现了。