【问题标题】:Unity array, get current index -x or +x [duplicate]Unity数组,获取当前索引-x或+x [重复]
【发布时间】:2020-08-06 10:36:46
【问题描述】:

例如,我如何获得当前索引 -5。我知道如何获取当前索引,并且可以减去或添加到该索引,但这会导致 Array 越界错误。假设数组有 15 个项目(索引 0/14),我当前的索引是 2,如果我减去 5,它将返回 -3。这在数组中不存在。现在我想要的是,当索引为 2 并且我减去 5 时它返回 11,所以它应该始终循环遍历数组。显然,这同样适用于添加 5。

【问题讨论】:

  • 你能告诉你到目前为止你尝试了什么吗?
  • 在这种情况下,我目前只尝试了 x (5) 的减法或加法,但这给出了超出范围的错误。老实说,当我减去接近 0 索引或添加接近数组长度时,我不知道如何知道 x 的余数是多少。
  • 如果你只是想循环一个数组,当数字超出下端的界限时,你可以添加数组的长度,当它超出界限时上端你可以减去数组的长度。只要您添加/减去的数量小于数组的长度,那应该可以。如果可以帮助您将其可视化,请在纸上写一些场景(起始索引、结果索引、所需索引)。
  • 该死的,这太明显了,我不明白为什么我完全错过了这个:像 if(_currentIndex array.Length) {_currentIndex -= _array.Lenght}应该做对吗?
  • 确实应该。

标签: c# arrays unity3d indexing circular-buffer


【解决方案1】:

你可以像这样创建一个扩展方法:

public static int ComputeCircularIndex(this Array arr, int i) 
{
   int N = arr.GetLength(0);
   if (i < 0) 
   {
       i = N + (i % N);
   } 
   else 
   {
       i = i % N;
   }
   return i;
}

【讨论】:

  • 您可以编辑您的答案以便编译吗?目前n(相对于N)是未定义的,它不会返回任何东西。
  • 没关系,我为你修好了,因为这对我来说似乎是更优雅的解决方案。
  • 这会是更优雅的解决方案@John 吗?老实说,我不明白我会怎么称呼它。
  • @QuincyNorbert Nick 编写了它,以便您可以在静态类中声明它,然后简单地调用 myArray.ComputeCircularIndex(-5)(参见 extension methods),或者您可以简单地删除“this”并调用它作为ComputeCircularIndex(myArray, -5)
  • 看起来确实很优雅,感谢您的解释!
【解决方案2】:

使用modulo 运算符,您可以很容易地实现第二行为(增加索引并循环抛出数组)。对于第一个行为,您需要一些额外的逻辑。这是fiddle

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyClass: MonoBehaviour
{
   private int currentIndex = 0;

   void Increment(int value)
   {
      currentIndex += value;
      currentIndex = currentIndex % 15;
   }

   void Decrement(int value)
   {
      currentIndex -= value;

      if (currentIndex < 0)
          currentIndex = 15 + (currentIndex % 15);
   }
}

【讨论】:

  • 我假设,这样做时,数组中的 15 项是固定的,对吗?因此,例如,当数组包含 20 个项目时,% 15 和 15 - 1 - currentIndex 变为 % 20 和 20 - 1 - currentIndex?
  • 是的,完全正确。我更新了答案,使代码更具可读性和简单性,在每种情况下都使用模数。
【解决方案3】:

您可以使用下面的代码来确保索引在范围内。 它将添加数组的长度,因此负数将在范围内。 如果是正数、正确的索引,这样的添加会导致索引超出范围,因此我使用 mod % 运算符再次确保我们在范围内。

var numbers = Enumerable.Range(0, 15).ToArray();
var idx = 2;
var offset = 5;
idx = (idx - offset + numbers.Length) % numbers.Length;
var el = numbers[idx];

el 将等于 12。

为确保offset 的大值得到正确处理,您可以使用numbers.Length 的任意倍数,例如。

idx = (idx - offset + 100 * numbers.Length) % numbers.Length;

【讨论】:

  • 请注意,副本中的答案正确地处理了更大的偏移量(如 100) - 您可能需要澄清这一点。
  • @AlexeiLevenkov 谢谢,我希望新的Index 对象可以在不指定^ 的情况下默认处理负索引,无论如何这需要正值..
猜你喜欢
  • 2018-02-03
  • 1970-01-01
  • 2016-08-21
  • 2013-10-05
  • 1970-01-01
  • 2021-11-12
  • 2017-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多