【问题标题】:Get array values from specific index with specified length [closed]从具有指定长度的特定索引获取数组值[关闭]
【发布时间】:2019-08-09 07:56:19
【问题描述】:

我正在做一些代码挑战,我想通过指定起始索引并仅从起始索引中获取第一个(3 个或任何长度)值来从我的数组中获取前 3 个值。

我试过这段代码,它可以工作,但是代码结构太长了,我怎样才能把它缩短,以便于理解。

            int n = 10;
            double signature = new double[] { 1, 1, 1 };
            double[] ret = new double[n];
            double sum = 0;
            ret[0] = signature[0];
            ret[1] = signature[1];
            ret[2] = signature[2];
            int x, i;

            for (i = 0; i < n - signature.Length; i++)
            {
                for(x = i; x <= signature.Length + i; x++)
                {
                    sum += ret[x];
                }
                ret[x - 1] = sum;
                sum = 0;
            }

            return ret;

【问题讨论】:

  • 您当前的代码似乎与您当前在问题文本中描述的不符。你能说清楚你想要什么吗?
  • 您的代码与您的问题不符。您是否要在移动的起始索引上计算三个元素的某种总和?
  • FWIW,您是如何决定 Linq 将为您提供性能的?它为您提供可读性和其他情况下的懒惰阅读,但在您展示的示例中,我认为 Linq 不会让程序运行得更快。
  • @John 我只是希望我的代码更短。
  • @jkdev 你说得对,我是堆栈溢出的新手,我花时间完全理解它的每个部分,这是我第一次看到代码审查。下次遇到这种情况我会使用 Code Review 谢谢!

标签: c# arrays linq


【解决方案1】:

没有Linq解决方案:

private static T[] Extract<T>(T[] source, int fromIndex, int length) {
  if (null == source)
    throw new ArgumentNullException(nameof(source));
  else if (fromIndex < 0)
    throw new ArgumentOutOfRangeException(nameof(fromIndex), 
                                         "From Index must be non-negative");
  else if (length < 0)
    throw new ArgumentOutOfRangeException(nameof(length), 
                                         "Length must be non-negative");

  if (fromIndex >= source.Length || length == 0)
    return new T[0];

  T[] result = new T[Math.Min(length, source.Length - fromIndex)];

  Array.Copy(source, fromIndex, result, 0, result.Length);

  return result;
}

然后

 double[] signature = new double[] { 0, 1, 2, 3, 4, 5 };
 double[] ret = Extract(signature, 3, 2);

 Console.Write(string.Join(", ", ret));

结果:

 3, 4

【讨论】:

  • 谢谢,但是使用非 linq 解决方案真的更好吗?
  • @Keith:更快(Linq 将创建IEnuemrable&lt;T&gt;、中间List&lt;T&gt; 等,例如,如果您想从 10 亿个数组中提取 100 万个项目,它会很有用);我还添加了验证:如果sourcefromIndexlength 无效,则您有一个可读异常
【解决方案2】:

使用 LINQ,您可以尝试以下操作:

var values = array.Skip(index)
                  .Take(n)
                  .ToArray();

其中index 是第一个项目的索引,n 是您要选择的项目的数量。

例如https://dotnetfiddle.net/Pk1rwY

作为旁注。使用 LINQ 并不意味着您的代码会更快。它会更紧凑/可读等。为了评估代码的性能,您必须使用BenchmarkDotNet之类的东西。

【讨论】:

  • 这正是我要找的,谢谢!!!
  • @Keith 不客气。我很高兴能帮上忙:)
【解决方案3】:

根据您的问题,您需要利用运算符.Take.Skip

   var result = array.Skip(startingIndex).Take(numberOfElements);

因此,从您的代码来看,您似乎正在尝试做一些不同的事情,即对元素求和。 .Sum 操作符在这里可能会有所帮助。

【讨论】:

  • 感谢您指出使用 .Sum 运算符。 :))
猜你喜欢
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 1970-01-01
  • 2014-02-27
  • 1970-01-01
  • 2021-09-07
  • 2021-01-22
  • 1970-01-01
相关资源
最近更新 更多