我有2d类似的aray:
string[,] arr = {
{ "A", "A", "A", "A", "A", "A", "A", "D", "D", "D", "D", "D", "D", "D", "D" },
{ "1", "1", "1", "1", "1", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0" },
{ "2", "2", "2", "2", "2", "2", "2", "00", "00", "00", "00", "00", "00", "00", "00" }
};
我想从上面的数组得到以下结果:
A 1 2
A 1 2
A 1 2
A 1 2
A 1 2
A 1 2
从数组中获取长度为0的所有“A”。从其他列获取它的腐蚀值。 这是一个大的2d数组,值超过6k。但设计与上述完全相同。到目前为止,我尝试了两种方法:
第一种方法:使用for循环遍历所有值:
var myList = new List<string>();
var arrLength = arr.GetLength(1)-1;
for (var i = 0; i < arrLength; i++)
{
if (arr[0,i].Equals("A"))
myList.Add(arr[0, i]);
else
continue;
}
}
第二种方法:创建列表而不是遍历所有值:
var dataList = new List<string>();
var list = Enumerable.Range(0, arr.GetLength(1))
.Select(i => arr[0, i])
.ToList();
var index = Enumerable.Range(0, arr.GetLength(1))
.Where(index => arr[0, index].Contains("A"))
.ToArray();
var sI = index[0];
var eI = index[index.Length - 1];
myList.AddRange(list.GetRange(sI, eI - sI));
它们似乎都很慢,效率不高。有没有更好的方法呢?
答案 0 :(得分:2)
我喜欢以我的代码最终自我记录的方式来处理这些算法。通常,使用您的代码描述算法,而不是使用代码功能使其膨胀,往往会产生非常好的结果。
var matchingValues =
from index in Enumerable.Range(0, arr.GetLength(1))
where arr[0, index] == "A"
select Tuple.Create(arr[1, index], arr[2, index]);
对应于:
// find the tuples produced by
// mapping along one length of an array with an index
// filtering those items whose 0th item on the indexed dimension is A"
// reducing index into the non-0th elements on the indexed dimension
只要您遵循简单的“地图,过滤,减少”范例并避免引入副作用,这应该非常好地并行化。
修改强>
为了返回与“A”关联的列的任意集合,您可以:
var targetValues = new int[] { 1, 2, 4, 10 };
var matchingValues =
from index in Enumerable.Range(0, arr.GetLength(1))
where arr[0, index] == "A"
select targetValues.Select(x => arr[x, index]).ToArray();
要使其成为完整的集合,只需使用:
var targetValues = Enumerable.Range(1, arr.GetLength(0) - 1).ToArray();
答案 1 :(得分:1)
正如“usr”所说:如果你想要原始性能,请回到基础。还要考虑到“A”值可以从索引&gt;开始。 0:
var startRow = -1; // "row" in the new array.
var endRow = -1;
var match = "D";
for (int i = 0; i < arr.GetLength(1); i++)
{
if (startRow == -1 && arr[0,i] == match) startRow = i;
if (startRow > -1 && arr[0,i] == match) endRow = i + 1;
}
var columns = arr.GetLength(0);
var transp = new String[endRow - startRow,columns]; // transposed array
for (int i = startRow; i < endRow; i++)
{
for (int j = 0; j < columns; j++)
{
transp[i - startRow,j] = arr[j,i];
}
}
首先初始化新阵列(然后设置“单元格值”)是主要的性能提升。