我还有另一个与此相关的问题: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很新,请给我一个手!
答案 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
的路线。