【问题标题】:sort collection by specific type c#按特定类型对集合进行排序c#
【发布时间】:2014-11-23 12:58:05
【问题描述】:

我收集了一组场景(Enterprise Architect 场景)。每个场景都有一个类型,我想从特定场景开始循环遍历集合。

我想开始循环的场景类型为“基本路径”,它包含有关其他场景的一些信息(我认为这是企业架构师中的一个错误,但它与这个问题无关。我只是想指出我为什么要从这个场景开始)。

Collection scenarios = element.Scenarios;
//Sort the collection?

foreach (Scenario sc in scenarios)
{
    //Start with the scenario that has "Basic Path" type
}

该集合只能具有该类型的一种方案。如何让 foreach 语句从该场景开始?

编辑: 其余场景的顺序无关紧要。

【问题讨论】:

  • 那里似乎有两个问题——一个关于排序,一个关于跳过。您真的要排序并跳过吗?
  • 我不想跳过任何场景。我只想从那个场景开始循环遍历集合。
  • 感谢那个在没有评论的情况下投反对票的人。这绝对是人们学会提出更好问题的方式..
  • 但这意味着什么?假设起始场景位于索引 10,并且集合中有 15 个项目。这是否意味着您要按 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 的顺序访问元素?如果不是,那么您究竟希望元素如何排序?
  • 这正是我想要的。其余的顺序无关紧要,因为我想从该特定元素开始的唯一原因是它包含有关其他元素的信息。

标签: c# sorting collections


【解决方案1】:

你不能。您需要根据您的规格重新排序它们。或者让 element.Scenarios 成为您特定的集合并按照您想要的方式实现它。

【讨论】:

    【解决方案2】:

    您的问题有点稀疏,我不太确定您使用的是哪种集合类型(不过,您应该更改为使用通用类型)。但这样的事情会奏效。

    Collection scenarios = element.Scenarios
                                  .Cast<Scenario>()
                                  .OrderBy(c => c.type == "Basic Path" ? 0 : 1);
    
    foreach (Scenario sc in scenarios)
    {
        //Start with the scenario that has "Basic Path" type
    }
    

    当类型为“基本路径”时,这将通过为元素分配排序值01 来对元素进行排序。因此,它们将首先出现。

    虽然我不知道你为什么想要一个 foreach 来迭代需要按特定顺序排列的类型,就像这样。肯定有这样做的时候,但这感觉像是一个混乱的实现。

    或者,既然你说只有一个,你可以这样做。

    var BasicPath = element.Scenarios
                           .Cast<Scenario>()
                           .SingleOrDefault(c => c.type == "Basic Path");
    

    如果返回多个并不表示数据损坏,您也可以只使用FirstOrDefault

    然后你可以用这个迭代其他人。

    foreach (var v in element.Scenarios.Cast<Scenario>().Where(c => c.type != "Basic Path"))
    {
        // definitely not the same as that first one.
    }
    

    【讨论】:

    • 这是一个企业架构师集合。我认为类型是 IDualCollection。
    • @n.Stenvang 好吧,无论如何,如果我理解正确的话,其中一个应该做你想做的。
    • 我已尝试实施这两个建议,它们都按预期工作。谢谢你的回答 - 赞成!看来我可以使用一些关于这个主题的教程。
    • @n.Stenvang 很高兴能提供帮助。对于它的价值,这个解决方案使用 LINQ。您可能想阅读一些内容以及如何利用它。我确信 MSDN 上有一些很好的文章。
    【解决方案3】:

    你能不能把你的类型变成一个类而不是一个字符串,并给它一个属性来表示你想要处理项目的顺序。因此,“基本类型”的序列可能为 1。然后您可以按此序列对查询进行排序。

    【讨论】:

      【解决方案4】:

      您可以使用SkipWhile()TakeWhile() 的组合来执行此操作,两者都使用相同的谓词。

      这是一个带有整数列表的示例(为简单起见):

      IEnumerable<int> sequence = Enumerable.Range(0, 15);
      
      Func<int, bool> predicate = x => x != 10;
      
      var result = 
          sequence.SkipWhile(predicate)
          .Concat(sequence.TakeWhile(predicate));
      
      // This prints
      // 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
      
      Console.WriteLine(string.Join(", ", result));
      

      对于您的示例,它可能类似于:

      Func<Scenario, bool> predicate = s => s.Type != "Basic Path";
      
      var sequence = 
          scenarios.SkipWhile(predicate)
          .Concat(scenarios.TakeWhile(predicate));
      

      【讨论】:

      • 收到以下错误:实例参数:无法从 'EA.Collection' 转换为 'System.Collections.Generic.IEnumerable'
      【解决方案5】:

      在订购之前,您不能枚举以特殊实例开头的 IEnumerable 集合。 如果不想下单收货,还有其他办法:

      var bpScenario = element.Scenarios.First(o=> {your condition to get your "Basci Path"(what is it? Is this Type or field value or what?)});
      //
      // here process your "Basic Path" scenario
      //
      foreach(var scenario in element.Scenarios.Where(o=> {condition where not "Basic Path" scenario}))
      {
      // process your other scenarios
      }
      

      【讨论】:

        猜你喜欢
        • 2021-03-13
        • 1970-01-01
        • 2011-02-10
        • 2021-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-08
        • 1970-01-01
        相关资源
        最近更新 更多