我有一个过滤方法,它使用动态linq获取结构的泛型数组,执行查询和/或orderby和/或将表达式作为字符串,并返回匹配索引的列表,然后使用通过外部程序。
我最初采用了一些粗略且准备好的方法来获取索引列表,只需迭代原始列表并找到项目与筛选列表中的项目相等的位置,如下所示:
public static int[] FilterStructs<T>(IList<T> structs, string query = "", string orderBy = "", int topN = 0) where T : struct {
var filteredStructs = structs.AsQueryable();
if (!string.IsNullOrEmpty(query)) filteredStructs = filteredStructs.Where(query);
if (!string.IsNullOrEmpty(orderBy)) filteredStructs = filteredStructs.OrderBy(orderBy);
if (topN > 0) filteredStructs = filteredStructs.Take(topN);
return GetArrayIndexList(structs, filteredStructs.ToArray());
}
private static int[] GetArrayIndexList<T>(IList<T> arrMain, T[] arrFiltered) where T : struct {
List<int> indexes = new List<int>();
for (int i = 0; i < arrFiltered.Length; i++) {
for (int j = 0; j < arrMain.Count; j++) {
if (arrMain[j].Equals(arrFiltered[i])) {
indexes.Add(j);
break;
}
}
}
return indexes.ToArray();
}
然而,当结构数组中甚至有几千个项目时,这变得非常慢。
我理想的做法是,最初使用动态select语句将结构数组投影到一个带有附加&#34;索引的新数组中。字段,执行过滤,然后从select语句中仅返回这些索引值将是微不足道的。
但是,我在如何实现这一目标方面略有一点空白。
感谢任何建议。
答案 0 :(得分:0)
如果我理解正确,过滤后的数组元素将保证存在于原始数组中,因此您可以使用以下内容替换GetArrayIndexList主体。
angular.module('portal', [
'ui.router',
'ceibo.components.table.export',
'portal']); //REMOVE THIS
})();
答案 1 :(得分:0)
它比我想象的要简单,虽然这不是我理想的解决方案,因为我必须更改查询和orderby子句的每个传入字符串表达式以包括预计的实体名称。它虽然有效,所以它现在可以用,直到我有更多的时间。
public static int[] FilterStructs<T>(IList<T> structs, string query = "", string orderBy = "", int topN = 0) where T : struct {
var withIndex = structs.Select((s, i) => new { index = i, item = s });
var filteredStructs = withIndex.AsQueryable();
if (!string.IsNullOrEmpty(query)) filteredStructs = filteredStructs.Where(query);
if (!string.IsNullOrEmpty(orderBy)) filteredStructs = filteredStructs.OrderBy(orderBy);
if (topN > 0) filteredStructs = filteredStructs.Take(topN);
return filteredStructs.Select("index").Cast<int>().ToArray();
}
例如,如果我之前的where子句是“value = 123”,那么它现在必须变成“item.value = 123”。