List<> 获取下一个元素或获取第一个

Posted

技术标签:

【中文标题】List<> 获取下一个元素或获取第一个【英文标题】:List<> Get Next element or get the first 【发布时间】:2009-04-22 11:20:59 【问题描述】:

我想获取列表中的下一个元素,如果列表在其末尾,我想要第一个元素。 换句话说,我只想让它循环。

   List<int> agents = taskdal.GetOfficeAgents(Branches.aarhusBranch);
    if (lastAgentIDAarhus != -1)
    
        int index = agents.IndexOf(lastAgentIDAarhus);
        if (agents.Count > index + 1)
        
            lastAgentIDAarhus = agents[index + 1];
        
        else
        
            lastAgentIDAarhus = agents[0];
        
    
    else
    
        lastAgentIDAarhus = agents[0];
    

我对上面显示的我自己的解决方案相当不满意,如果你有更好的解决方案,请告诉我:)

【问题讨论】:

【参考方案1】:
lastAgentIDAarhus = agents[index == -1 ? 0 : index % agents.Count];

MOD 运算符 % 的使用自动将索引切分到可能索引的范围内。

模运算符是对 DIV (/) 运算符的补充,它返回两个整数相除的余数。例如,如果您将 9 除以 6,则结果为 1,余数为 3。MOD 运算符要求 3。

【讨论】:

哇,如果可行的话,这是一个非常简洁的解决方案:) 愿意解释一下吗? mod 运算符进行模运算,这正是您想要的。如果您可以将索引初始化为 0 而不是 -1,您可以使用:lastAgentIDAarhus = agent[index % (agents.Count - 1)] 我觉得应该是index % ( agents.Count ) @EricYin:您的 Count 将始终比您拥有的最高索引高 1。这是因为(通常)索引从 0 开始,而 Count 属性从 1 开始。 @EricYin 是正确的。假设您有一个包含 10 个项目的列表,并且您尝试访问索引 10 处的项目(它不存在)。 10%10=0 是你想要的,而不是 10%9=1。【参考方案2】:

或者简单地说:

public static T NextOf<T>(this IList<T> list, T item)

    var indexOf = list.IndexOf(item);
    return list[indexOf == list.Count - 1 ? 0 : indexOf + 1];

例子:

List<string> names = new List<string>();

names.Add("jonh");
names.Add("mary");

string name = String.Empty;    

name = names.NextOf(null);   //name == jonh

name = names.NextOf("jonh"); //name == mary

name = names.NextOf("mary"); //name == jonh

【讨论】:

【参考方案3】:

作为对此略有不同的看法,这里有一个扩展方法,您可以使用它来使任何 IEnumerable '循环'

  public static IEnumerable<T> AsCircularEnumerable<T>(this IEnumerable<T> enumerable)
  
    var enumerator = enumerable.GetEnumerator();
    if(!enumerator.MoveNext())
      yield break;

    while (true)
    
      yield return enumerator.Current;
      if(!enumerator.MoveNext())
        enumerator = enumerable.GetEnumerator();
    
  

所以你可以像这样使用它

  var agents = new List<int> 1, 2, 3, 4, 123, 234, 345, 546;

  foreach(var i in agents.AsCircularEnumerable())
  
    Console.WriteLine(i);
  

这将继续进行...... :)

【讨论】:

如果列表中有 3 个元素,并且如果我使用 4 或 5 的索引值 - 获取列表中的项目 - 我会得到列表的第一个和第二个元素吗? 我不确定你的意思。如果您询问使用我上面概述的解决方案进行索引,因为这不是一个列表,它是一个 IEnumerable,并且您不能在 IEnumerable 上使用索引器,那么不,您不会。您可以改用agents.AsCircularEnumerable().Skip(10).First() 之类的东西。【参考方案4】:

我喜欢Vinicius's idea 使用扩展方法。不幸的是,他发布的代码会引发异常。这是基于他的,但它不会抛出异常并且非常简单易读(恕我直言):

public static T Next<T>(this IList<T> list, T item)

    var nextIndex = list.IndexOf(item) + 1;

    if (nextIndex == list.Count)
    
        return list[0];
    

    return list[nextIndex];

如果传入的项不在列表中,它将返回列表中的第一项,因为list.IndexOf(item)在这种情况下将返回-1

【讨论】:

Koveras,哪里会引发异常? 记住 list.IndexOf(item) 将返回 -1 如果没有找到项目。 这对于扩展来说确实是个好主意。我对其进行了一些修改并实现了它:)【参考方案5】:

差别不大,但至少少了一些代码(至少在编辑器中);o)

List<int> agents = taskdal.GetOfficeAgents(Branches.aarhusBranch);
if (lastAgentIDAarhus != -1)

    int index = agents.IndexOf(lastAgentIDAarhus);
    lastAgentIDAarhus = (agents.Count > index + 1 ? agents[index + 1] : agents[0]); 

else

    lastAgentIDAarhus = agents[0];

【讨论】:

【参考方案6】:

如果我们添加一些检查来避免常见错误,您怎么看?

public static class ListExtensions

    public static TType Next<TType>(this IList<TType> list, TType item)
    
        if (list == null) return default(TType);

        var itemIndex = list.IndexOf(item);
        if (itemIndex < 0) return list.FirstOrDefault();

        var nextIndex = itemIndex + 1;

        return nextIndex >= list.Count 
            ? list.FirstOrDefault() 
            : list[nextIndex];
    

【讨论】:

【参考方案7】:

字符串 line = lines[lines.FindIndex(x => x.Contains(item)) + 1];

【讨论】:

以上是关于List<> 获取下一个元素或获取第一个的主要内容,如果未能解决你的问题,请参考以下文章

将list中某个元素放到第一的位置改怎么做

C#GetType():代码如何在没有实际元素的情况下获取 List<T> 中 T 的类型? [复制]

jquery获取子元素

XPath 仅在任何其他元素之前获取第一个子注释

c# 如何获取列表中某个属性最大或最小的元素?

如何利用JavaScript语言获取Map集合中元素个数