【问题标题】:Find index of item from string array containing comma separated values从包含逗号分隔值的字符串数组中查找项目的索引
【发布时间】:2017-03-14 08:17:39
【问题描述】:

下面是我的字符串数组:

string[] arr = { 
                 "region1.mp3,region1-sub.mp3,region1-sub1.mp3,region2-sub.mp3", 
                 "region2.mp3,region2-Sub1.mp3",
                 "region3.mp3" 
               };

下面是我试图在上面的字符串数组中搜索并获取索引的值:

string searchItem = "region1-sub1.mp3";

这就是我尝试搜索但得到 -1 的方式(-1 表示我猜未找到搜索):

int index = Array.FindIndex(arr, t => t == searchItem); // -1

我明白,因为我在字符串数组中的记录是用逗号分隔的,这就是搜索失败的原因。

那么还有其他方法可以帮助我找到索引而不循环和生成新的字符串数组吗?

预期输出:0

【问题讨论】:

  • 你试过Contains ??
  • int index = Array.FindIndex(arr, t => t.Split(',').Contains(searchItem));
  • 你有一个字符串数组,而不是逗号分隔的值。电脑不知道,在这里有特殊含义。如果要搜索单个值,则必须先拆分字符串,或使用string.Contains 或正则表达式以获得更好的性能
  • @Learning 你为什么这么认为?在大多数情况下,它实际上更快,因为它不需要像拆分这样的任何字符串操作,并且在您特别要求它们之前不会返回任何结果。它只返回指向原始字符串的指针。 IsMatch,甚至没有
  • @Learning 至少数量级。这就是为什么管理员在 shell 脚本中使用正则表达式而不是手动拆分字符串的原因。部分原因是正则表达式会导致构建用于匹配模式的解析器。它可以通过读取字符流来做到这一点,它不必为了拆分它而读取所有内容。这使用的 CPU 和 RAM 显着减少。另一部分是结果是原始字符串的索引集合。只有当您使用.Value 请求一个值时,才会创建一个字符串。这节省了 CPU 和 RAM 并且避免了 GC 数千个字符串的惩罚

标签: c# linq


【解决方案1】:

你想用逗号分割每个字符串:

int index = Array.FindIndex(arr, t => t.Split(',').Contains(searchItem)); 

即使字符串不包含逗号,这也有效。

【讨论】:

  • 请注意,这只有在 searchItem 完全匹配时才有效。如果 searchItem="region1-sub1" 则结果为 -1。如果 searchItem 可以是部分字符串,则使用 Contains without Split。
  • @RuardvanElburg:当然,这就是我理解 OP 要求的方式。音频文件用逗号分隔。它还返回所需的结果。你不能用这种方法搜索".mp3"。如果需要,他需要更改查询,例如:Array.FindIndex(arr, t => t.Split(',').Select(Path.GetExtension).Contains(".mp3"))
  • 是的,这行得通。非常感谢您为帮助我所做的努力。谢谢。只是想问您一件事,1 位用户指出使用正则表达式在这方面会有很好的表现。什么你觉得呢??
  • @Learning:正则表达式的效率低于纯字符串方法。更重要的是:对于大多数人来说,它的可读性也较低。如果可能,我会尽量避免使用正则表达式。
  • @TimSchmelter 用于直接匹配,也许。在这种情况下,虽然它会更快,因为它会避免生成临时字符串。至于可读性——一旦你使用 Splunk,或者必须解析大型日志文件,它就会变得容易得多
【解决方案2】:

这将为您提供所需的输出。

int index = Array.FindIndex(arr, t => t.Contains(searchItem));

【讨论】:

  • 它并不总是有效,但在这种情况下,当每个文件名都以region 开头并以.mp3 结尾时,您可以使用简单的包含。否则,您应该拆分每个字符串以分别检查文件名
  • 同意。这只是基于其数组中元素的标准格式对 OP 的修复。他甚至可以从搜索项中去掉“.mp3”后缀。
  • 如果他从搜索中删除文件扩展名,那么您的代码将无法工作。 region2 将匹配 region2.mp3region2-sub.mp3
  • region2 != region2-sub
  • "region2-sub".Contains("region2") == "region2".Contains("region2")
【解决方案3】:

int index = Array.FindIndex(arr, t => t.Contains(searchItem));

这将返回 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 2013-01-08
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    相关资源
    最近更新 更多