【问题标题】:How to select sections of differing lengths from list using LINQ only如何仅使用 LINQ 从列表中选择不同长度的部分
【发布时间】:2013-06-21 11:04:09
【问题描述】:

我有一个名为“复杂”类型的列表:

List<Complex> list = new List<Complex>();
...
class Complex
{
  public string Header { get; set; }
  ...
  ...
  ...
}

列表中有一些重复的标题,这些表示新部分的开始。每个部分的长度可能不同,如下所示:

start 1 2 3 4 5 6 7 start 1 2 3 start 1 2 3 4 5 6 start 1 start 1 2

我想使用 LINQ 获取所有可能的 Complex 类型的子列表;也就是所有带头的对象,如下:

  • 1 2 3 4 5 6 7
  • 1 2 3
  • 1 2 3 4 5 6
  • 1
  • 1 2

我怎样才能仅使用 LINQ 完成此操作?

编辑: 在html页面解析期间创建列表

<tr>
                                                <td>00:00<!--//-00:00--></td>
<td>15:00<!--//-00:00--></td>
<td class="txt_left"><a href="">News</a></td>
<td><a href="/TsV2/TV_Video_On.asp?PROG_CODE=TVCR0114">
<img src="/images/new/sub_new/icon_play01_off.gif" alt="play"  class="rollover"/></a></td>

</tr>

<tr>
                                                <td>00:15<!--//-00:00--></td>
<td>15:15<!--//-00:00--></td>
<td class="txt_left">
<a href="Tv_Pagego.asp?PROG_CODE=TVCR0556">Nice one</a></td>
<td><a href="/TV2w/TV_2Video_On.asp?PROG_CODE=TVCR0556"><img src="/images/new/sub_new/icon_play01_off.gif" alt="play"  class="rollover"/></a></td>

</tr>

【问题讨论】:

  • 标头是唯一值还是始终相同(“开始”)?
  • 在“重复标题”的问题中,您是否尝试过 .GroupBy(x => x.Header)?
  • @DaveWilliams Group by 在这种情况下不起作用。
  • 你需要使用 LINQ 吗?它是一个简单的运行槽经典循环。
  • @AdamHouldsworth 为什么不呢?如果标题只是问题中列出的标题,它会起作用,否则问题应该更清楚......

标签: c# .net linq


【解决方案1】:
static void Main(string[] args)
        {
            var seq = new object[] {"start", 1, 2, 3, 4, "start", 1, 2, 3, "start", 1, 2, "start", 1};

            var no = 0;

            var test = (from i in seq select new {SeqNo = (i.ToString() == "start" ? no++ : no), Item = i}).Where( x => x.Item.ToString() != "start").GroupBy( y => y.SeqNo ).Select( z => z.ToArray()).ToArray();


        }

var test = (from i in seq
                       group i by i.ToString() == "start" ? ++no : no into g
                       select g.Where( gi => gi.ToString() != "start" ).ToArray()
                       ).ToArray()
                       ;

ToArray 语句不是必需的

【讨论】:

  • 很好地提供了一个“linq”解决方案,但我仍然建议不要触摸它,因为它读起来很麻烦! :-)
  • 你是个天才! :D 它有效。 var test = (from i in fulllist select new {SeqNo = (i.Header == "start" ? no++ : no), Item = i}).Where( x => x.Item.Header != "start") .GroupBy( y => y.SeqNo ).Select( z => z.ToArray()).ToArray();
  • 您也可以将迭代器应用到 Linq 函数 complexList.Select((complex, i) =&gt; new { Number = complex.Header.Equals("Start") ? i++ : i, Complex = complex })
【解决方案2】:

这个问题对我来说不是很清楚,但这里有一些提示:

  • 使用 .Distinct() 获得独特的结果
  • 试试 GroupBy(c => c.Header)
  • 如有必要,使用 string.Split 拆分字符串值

【讨论】:

    【解决方案3】:
    var List = new List<Complex>()
    {
        new Complex() { Header = "start" },
        new Complex() { Header = "00:23" },
        new Complex() { Header = "00:33" },
        new Complex() { Header = "start" }
    };
    
    var query = List.GroupBy(x => x.Header);
    

    这将产生 3 个 IGrouping,一个带有标题“Start”,一个带有“00:23”,一个带有“00:33”

    更具体地说,查询将返回一个 IEnumerable>,其中 Keys 将是您的标题。元素将是您的类型(复杂)。

    编辑:问题似乎不是这个问题,但这是:)

    var seq = new object[] {"start", 1, 2, 3, 4, "start", 1, 2, 3, "start", 1, 2, "start", 1}.ToList();
    
    while(seq.Count() != 0)
    {
        var Output = seq.SkipWhile(x => x.ToString() != "start").Skip(1).TakeWhile(x => x.ToString() != "start");
        seq.RemoveRange(0, Output.Count() +1);
    }
    

    我喜欢...

    【讨论】:

    • 添加的顺序很重要。它是在解析 html 文件时创建的列表。
    • 这绝对不能提供所需的输出。
    • 这对答案有何影响?按您喜欢的任何顺序添加它们......如果您想获得具有相同标题的“子列表”,它们将与原始列表的顺序相同。至少我是这么认为的……
    • @AdamHouldsworth 你知道想要的输出吗?我正在给出我从问题中理解的答案。它给了我我认为他想要的输出。如果不是这种情况,那么提出问题的人可以给出一些进一步的解释,我会改变我的答案以适应。
    • 所需的输出,至少在我的理解中,写在问题上。列表子集的 4 个分组,由您遇到说“开始”的内容定义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 2012-03-12
    • 1970-01-01
    相关资源
    最近更新 更多