基于索引数组复制子数组

时间:2016-02-14 09:47:35

标签: c#

关于如何获得具有开始和结束索引或开始索引和长度的子数组,有很多答案。但我正在寻找一种基于索引数组获得子阵列的方法。 这就是我所拥有的(它工作得很好但看起来很笨重)。

//sample arrays (could be unordered)
double[] expiry= { 0.99, 0.9, 0.75, 0.60, 0.5, 0.4, ...};
double[] values = { 0.245, 0.24, 0.235, 0.22, 0.21, 0.20, ... };


//find index of all elements meeting criteria in array expiry
int[] expind = expiry
  .Select((b, i) => b == 0.75? i : -1)
  .Where(i => i != -1).ToArray();

//create new arrays of appropriate size
double[] newvalues = new double[expind.Length];

//populate new arrays based on index
for (int i = 0; i < expind.Length; i++)
  newvalues[i] = values[expind[i]];

//check values
foreach (var item in newvalues)
   Console.WriteLine(item);

请问有更高效,更通用的方法吗?

更新

下一次尝试(仍然不是超级高效,但至少无环路):

Array.Sort(expiry, values);     
double criteria = 0.75;
int start = Array.IndexOf(expiry, criteria);
int last = Array.LastIndexOf(expiry, criteria);
int length = last - start + 1;
double[] newvalues2 = new double[length];
Array.Copy(values, start, newvalues2, 0, length);

3 个答案:

答案 0 :(得分:5)

您好,您可以使用lambda表达式以这种方式找到值:

double[] newVals = values.Where((t, i) => expiry[i] == 0.75).ToArray();

答案 1 :(得分:3)

这更简洁一些。无需将索引实际放入expind数组中;只需将索引直接用于带有索引的Where()重载:

double[] newpoints = points.Where((p, i) => (expiry[i] == 0.75)).ToArray();
double[] newvalues = values.Where((v, i) => (expiry[i] == 0.75)).ToArray();

请参阅deeper discussion

现在,如果由于某种原因你已经有一个expind索引数组,但它没有来自expiry的原始数组,你可以这样做:

double[] newpoints = expind.Select(ind => values[ind]).ToArray();

答案 2 :(得分:2)

根据具体情况,这可能适合您。

private static IEnumerable<double> GetByCondition(List<double> expiry, List<double> value)
{
  for(int i = 0; i < expiry.Count; i++)
    if(expiry[i] == 0.75)
      yield return value[i];
}

此外,如果您的数组/列表经常使用,我会将其作为扩展方法。

public static IEnumerable<double> GetValuesByExpiry(
  this List<double> self, List<double> values)
{
  return GetByCondition(self, values);
}

正如@Corak所提到的,如果将这两个数组合并为一个由touples组成的数组,问题可能会一并消除。当然,如果适合你的情况。你可以zip them together