如何管理多个不断增长的列表?

3
程序开始收集游戏中友军/敌军小兵的数量。
 var eminions = MinionManager.GetMinions(Player.ServerPosition, 1500 MinionTypes.All, MinionTeam.Enemy).ToList();
 var aminions = MinionManager.GetMinions(Player.ServerPosition, 1500, MinionTypes.All, MinionTeam.Ally).ToList();

然后我使用一个函数将列表中找到的每个对象转换为距离:

 emd.Add(eminions[0].ServerPosition.Distance(aminions[i].ServerPosition)); //the count is 5

我们的列表'emd'包含(aminions.Count)个距离,在我们的例子中=5。
emd[0] = 500 emd[1] = 400 emd[2] = 300 emd[3] = 200 emd[5] = 100
这里的难点在于,我们想要找出最小距离在列表中的位置。如果我们推测一下,我们可以看到它是emd[5]=100。但是怎么才能得到“5”呢?
总结:程序必须在列表中找到最小的数字,然后获取它所在的位置。
这是我尝试过的方法:我尝试比较每个数字,看哪个是最小的,如果是真的,就加入一个新列表,我面临的问题是创建了太多的列表,而且我没有准备好处理各种数量的小兵。
var eminions = MinionManager.GetMinions(Player.ServerPosition, 1500, MinionTypes.All, MinionTeam.Enemy).ToList();
var aminions = MinionManager.GetMinions(Player.ServerPosition, 1500, MinionTypes.All, MinionTeam.Ally).ToList();
if (eminions.Count > 0 && aminions.Count > 0)
{
    List<double> emd = new List<double>();
    List<bool> bdistance = new List<bool>();
    for (int i = 0; i < aminions.Count; i++)
    {
        emd.Add(eminions[0].ServerPosition.Distance(aminions[i].ServerPosition));

        for (int j = 0; j < aminions.Count; j++)
        {
            if (emd[i] > emd[j])
            {
                bdistance.Add(true);
            }
        }   
    }
}

标题非常不恰当。你要找的是最小值的索引。如何管理多个增长的列表?除此之外——我支持cramopy的答案最好——一个简单的循环。 - SimpleVar
3个回答

3
int pos = 0; // set index to zero
int min = emd[0]; // set minimum to first value
for (int i = 1; i < emd.Count; i ++)
{
    var val = emd[i]; // get value from position
    if (val < min) //check if value is smaller then current minimum
    {
        // set minimum to value
        min = val;
        // set minimum pos to current value pos
        pos = i;
    }
}
//found minimum
//minimum index == pos

你好,非常感谢你的贡献,我真的很感激。我认为这个可以行得通,但是你能加上注释吗?我想逐步了解这个答案的思路,谢谢! - user5738123
1
最后的 if 没有必要 - 它永远不会被触发。只有在 emd 为空时,索引才会被称为 -1(也就是未找到),在这种情况下,在开始时将抛出异常(我认为这是适当的)。移除最后一个 if,这就是最好的答案。循环比 Linq 更好! - SimpleVar
@adan-ramirez 为您添加了注释。 - cramopy
@SimpleVar移除了if语句,之前在更改逻辑后忘记移除它了...谢谢伙计!! - cramopy
是的,我会选择这个(写成一个单独的方法)。 - Matthew Watson

2

这应该可以工作

int indexMin
    = !emd.Any() ? -1 :
    emd.Select( (value, index) => new { Value = value, Index = index } )
    .Aggregate( (a, b) => (a.Value < b.Value) ? a : b )
    .Index;

1.如果列表为空,则!emd.Any() ? -1 :将强制为-1;

2.Select将每个int元素投影到一个具有两个属性(Value和Index)的匿名类型中:

3.Aggregate将获取具有最小Value的元素;

4.最后,我们得到所选元素的Index。


你好,非常感谢你的贡献,我真的很感激。我认为这个可以行得通,但是你能加上注释吗?我想逐步了解这个答案的思路,谢谢! - user5738123
2
这是一种让我犯难的代码示例,我会想:“Linq 还是普通代码?”...“算了吧,这个用普通代码就好了。” - Matthew Watson
@Fernando:“第一种方法的速度大约比第二种快1000倍”是什么意思?请解释。 - user5738123
@adanRamirez 第二种方法首先通过n次迭代(检查整个数组)获取最小值,然后找到该元素的索引,同时遍历整个数组。在cramopies解决方案中,它需要n次迭代,因为它只运行一次数组。 - Fernando
@adanRamirez 抱歉,两倍速度更快 :) - Fernando

2
您可以轻松找到它!
var minIndex = emd.IndexOf(emd.Min()); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接