如何在逗号分隔的字符串上执行Linq

时间:2017-03-15 07:35:12

标签: c# linq

我还有另一个与此相关的问题:Filter an IEnumerable in Linq with an array。但在此之后,我得到了一个新的要求,如

拥有数组string[] BranchIds = {"1","2","3"}

var a =_abc.GetRoutes(0)
    .Where(r => BranchIds.Contains(r.StringBranchIds))
    .ToList();

如果此代码中的StringBranchIds也是逗号分隔的字符串,该怎么办?

我尝试过这样的事情:

var a =_abc.GetRoutes(0)
    .Where(n => BranchIds.Contains((n.StringBranchIds.Replace(" ", "")
        .Split(',')
        .Select(m => Convert.ToInt32(m))
        .ToArray()).ToString()));

但没有去。

Contains内,我只能提供字符串。 Linq是这样的吗?

我对Linq很新,请给我一个手!

2 个答案:

答案 0 :(得分:2)

Contains方法询问单个值是否在更宽的序列/列表中。你不拥有那个;你有(对于每个分支):

  • StringBranchIds针对“路线”,我们可以相对轻松转换为平面列表
  • 一个BranchIds,这是我们正在测试的固定列表

无关。

假设你的意思是“任何交集”,那么这就像是:

var a =_abc.GetRoutes(0).Where(n =>
   n.StringBranchIds.Replace(" ", "").Split(',').Any(
        id => BranchIds.Contains(id)
   ));

这是做什么的:

  • StringBranchIds拆分为
  • 对于其中的每一个,测试它是否包含在BranchIds

但请注意,这在性能方面是最佳的 - 许多O(N)测试。如果BranchIds相对较小,您可能会很好(任何O(1)“改进”可能而不是O(N),对于小N }})。如果BranchIds ,您可以将其预处理为HashSet<string>等。

请注意,我没有向int解析任何内容 - 没有必要,这对您的表现没有帮助。

此外,您应该考虑将StringBranchIds预处理成适合测试的内容;这不一定涉及许多变化。例如,从这里:

public string StringBranchIds {get;set;}

我们可以改为:

private string _stringBranchIds;
public string StringBranchIds {
    get { return _stringBranchIds; }
    set {
        if(value != _stringBranchIds) {
            _stringBranchIds = value;
            _splitIds = null; // only if actually a change
        }
    }
}
private string _splitIds;
internal string[] GetSplitIds() {
    return _splitIds ?? (_splitIds =
        (_stringBranchIds ?? "").Replace(" ", "").Split(','));
}

现在我们只需更改方法以使用n.GetSplitIds()而不是n.StringBranchIds,它将返回相同的ID数组,直到值更改为止。比每次拆分要便宜得多。

答案 1 :(得分:0)

随你拆分逻辑

var a =_abc.GetRoutes(0).Where(r =>
          !r.StringBranchIds.Replace(" ", "").Split(',').Except(BranchIds).Any()).ToList();

这将仅返回StringBranchIds中包含所有BranchIds的路线。