【问题标题】:Check for next highest / lowest value in list and select that item检查列表中的下一个最高/最低值并选择该项目
【发布时间】:2015-06-04 00:13:22
【问题描述】:

更新:我应该更清楚。我正在尝试按升序对列表进行排序,然后获得比当前选择的武器具有更大价值的第一个武器。

我的 NextWeapon() 函数此时没有做任何事情(它只是在那里显示我尝试过的东西),但过去我只是迭代到列表中的下一个项目,但是一个项目可能不在。

枚举 F3DFXType 是我的角色可能拾取的武器,但如果它们实际上不在库存中,则循环遍历这些武器是没有意义的。因此,我尝试创建一个 int 类型的列表,然后循环遍历它。当角色拿起新武器时,它将作为 int 添加到列表中,然后当我切换到该 int 时,我会在 F3DFXType 枚举中检查相同的 int。

例如,在皮卡中,我会检查碰撞事件,然后使用: 武器列表.Add(5);认为它会将整数 5 添加到我的库存中。 F3DFXType 中的第 5 项是“Seeker”。当我尝试循环浏览我的库存时,它实际上不会添加第 5 个 F3DFXType,它只会在 F3DFXType 中添加 NEXT 项目。 (例如:我已经有 Vulcan,这将简单地添加 SoloGun,这是枚举中的第二项)


我正在尝试遍历列表中的项目。

我遇到的问题是,如果 Ito 迭代到列表中的下一个项目,该项目可能实际上并不存在。那么如何前进到列表中存在的下一个项目?

我不一定要使用下面的代码寻找答案,我只是想提供一些上下文,以便您可以看到我当前的方法。

// Possible weapon types
public enum F3DFXType
{
    Vulcan = 1,
    SoloGun,
    Sniper,
    ShotGun,
    Seeker,
    RailGun,
    PlasmaGun,
    PlasmaBeam,
    PlasmaBeamHeavy,
    LightningGun,
    FlameRed,
    LaserImpulse
}


 // List of weapons currently avaialable
public List<int> weaponList;
public int currentIndex = 1;


void NextWeapon()
    {
        // Keep within bounds of list
        if (currentIndex < weaponList.Count)
        {
            currentIndex++;

            // Check if a higher value exists
            var higherVal = weaponList.Any(item => item < currentIndex);

            // create a new list to store current weapons in inventory
            var newWeapList = new List<int>();
            foreach (var weap in weaponList)
            {
                newWeapList.Add(weap);
            }
            weaponList = newWeapList;

            // If a higher value exists....
            if (higherVal)
            {
                //  currentIndex = SOMEHIGHERVALUE
            }
        }        
    }



    void PrevWeapon()
    {
        if (currentIndex > 1)
        {
            currentIndex--;
        }
    }



  // Fire turret weapon
    public void Fire()
    {
        switch (currentIndex)
        {
            case 1:
                // Fire vulcan at specified rate until canceled
                timerID = F3DTime.time.AddTimer(0.05f, Vulcan);
                Vulcan();
                break;
            case 2:
                timerID = F3DTime.time.AddTimer(0.2f, SoloGun);
                SoloGun();
                break;
            case 3:
                timerID = F3DTime.time.AddTimer(0.3f, Sniper);
                Sniper();
                break;
            case 4:
                ShotGun();
                break;
            case 5:
                timerID = F3DTime.time.AddTimer(0.2f, Seeker);
                Seeker();
                break
           default:
                break;
        }
    }

【问题讨论】:

  • 我对你在这里尝试做的事情感到困惑。在weaponList.Any(item =&gt; item &lt; currentIndex); 为什么要与索引比较项目值?
  • 不太明白你想要完成什么。能不能详细解释一下?

标签: c# linq list unity3d


【解决方案1】:

如果我对问题的理解正确,我认为您可以简单地通过按升序对列表进行排序,然后获取比当前选择的武器具有更大价值的第一个武器。

例如:

void Next()
{
    var nextWeapon = weaponList
        .OrderBy(w => w)                         // Sort the weapon list
        .FirstOrDefault(w => w > currentIndex);  // Get the next highest weapon

    // If nextWeapon is 0, there was no higher weapon found
    currentIndex = nextWeapon > 0 ? nextWeapon : currentIndex;
}

编辑:

你也可以反过来得到之前的武器:

void PrevWeapon()
{
    if (currentIndex > 1)
    {
        var previousWeapon = weaponList
            .OrderByDescending(w => w)               // Sort the weapon list
            .FirstOrDefault(w => w < currentIndex);  // Get the next lowest weapon

        // If previousWeapon is 0, there is no next lowest weapon
        currentIndex = previousWeapon > 0 ? previousWeapon : currentIndex;
    }
}

【讨论】:

  • 这是一个很好的答案。我应该更清楚我最初在寻找什么(我已经更新了上面的文字)。此解决方案将返回列表中最高的武器,第二个选项将返回列表中的第一个武器。我仍在寻找一种方法来遍历列表中的所有内容,而不仅仅是这两项。我很抱歉没有说得更清楚。
  • 我认为我提供的代码实际上在做什么可能有点混乱。第一种方法按升序对列表进行排序,并且 get 是第一个具有比当前项目更大的值的武器(注意 lambda)。第二种方法反转此操作以获取第一个具有低于当前值的武器。这里的好处是 FirstOrDefault 只会枚举直到找到匹配项。无需枚举整个列表。
  • 嗯,也许我误会了?还是正确实施?当我使用它时,它会将我带到列表中的第一项或最后一项。
【解决方案2】:

我找到了解决方案。不知道为什么我花了这么长时间才弄清楚。无论如何,我现在可以使用它了。

我从库存中的 2 支枪开始。我现在只能在这两者之间切换。 (我的数组中的项目 0 和 4)。

当我与皮卡发生碰撞时,我可以将另一个物品添加到此库存(数组中的第 11 项)。

现在,当我点击 Previous 或 Advance 时,它​​知道要留在数组的范围内,如果没有找到更高的武器,则默认返回我们当前使用的武器。

// Weapon types
public enum F3DFXType
{
    Vulcan          = 0,
    SoloGun         = 1,
    Sniper          = 2,
    ShotGun         = 3,
    Seeker          = 4,
    RailGun         = 5,
    PlasmaGun       = 6,
    PlasmaBeam      = 7,
    PlasmaBeamHeavy = 8,
    LightningGun    = 9,
    FlameRed        = 10,
    LaserImpulse    = 11,
    MAX_WEAPONS     = 12
}


    public bool[] aWeaponsHave = new bool[(int)F3DFXType.MAX_WEAPONS];
    int iWeaponsCurrent;


public Constructor() 
{

       .....
     // Start at first weapon (VULCAN)
        iWeaponsCurrent = 0;
        aWeaponsHave[0] = true;

        // DEBUG: Add weapon to inventory
        aWeaponsHave[1] = true;
         .....
}



 private void GoNextWeapon()
    {
        // If there isn't a higher value found, then default back to the original one
        var originalVal = iWeaponsCurrent;

        do
        {
            iWeaponsCurrent++;
            // Went to the end of array & didn't find a new weapon. Set it to the original one. 
            if (iWeaponsCurrent == 12)
            {
                iWeaponsCurrent = originalVal;
                return;
            }
        } while (aWeaponsHave[iWeaponsCurrent] == false);
    }


    void GoPrevWeapon()
{
    do
    {
        iWeaponsCurrent--;

        // Prevent from spilling over
        if (iWeaponsCurrent < 0)
        {
            // Went to end of array. Set weapon to lowest value and get out of here
            iWeaponsCurrent = 0;
            return;
        }
    } while (!aWeaponsHave[iWeaponsCurrent]);
}



// Fire turret weapon
    public void Fire()
    {
        switch (iWeaponsCurrent)
        {
            //case F3DFXType.Vulcan:
            case 0:
                // Fire vulcan at specified rate until canceled
                timerID = F3DTime.time.AddTimer(0.05f, Vulcan);
                // Invoke manually before the timer ticked to avoid initial delay
                Vulcan();
                break;

            //case F3DFXType.SoloGun:
            case 1:
                timerID = F3DTime.time.AddTimer(0.2f, SoloGun);
                Debug.Log("Solo");
                SoloGun();
                break;

            //case F3DFXType.Sniper:
            case 2:
                timerID = F3DTime.time.AddTimer(0.3f, Sniper);
                Debug.Log("Sniper");
                Sniper();
                break;

            //case F3DFXType.ShotGun:
            case 3:
                timerID = F3DTime.time.AddTimer(0.3f, ShotGun);
                ShotGun();
                break;

            //case F3DFXType.Seeker:
            case 4:
                timerID = F3DTime.time.AddTimer(0.2f, Seeker);
                Seeker();
                break;

            //case F3DFXType.RailGun:
            case 5:
                timerID = F3DTime.time.AddTimer(0.2f, RailGun);
                Debug.Log("railgun");
                RailGun();
                break;
            //case F3DFXType.PlasmaGun:
            case 6:
                timerID = F3DTime.time.AddTimer(0.2f, PlasmaGun);
                PlasmaGun();
                break;

            //case F3DFXType.PlasmaBeam:
            case 7:
                // Beams has no timer requirement
                PlasmaBeam();
                break;

            //case F3DFXType.PlasmaBeamHeavy:
            case 8:
                // Beams has no timer requirement
                PlasmaBeamHeavy();
                break;

            //case F3DFXType.LightningGun:
            case 9:
                // Beams has no timer requirement
                LightningGun();
                break;

            //case F3DFXType.FlameRed:
            case 10:
                // Flames has no timer requirement
                FlameRed();
                break;

            //case F3DFXType.LaserImpulse:
            case 11:
                timerID = F3DTime.time.AddTimer(0.15f, LaserImpulse);
                LaserImpulse();
                break;
            default:
                break;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 2013-11-12
    • 1970-01-01
    相关资源
    最近更新 更多