代码之家  ›  专栏  ›  技术社区  ›  Pharabus

选择和跳过元素

  •  1
  • Pharabus  · 技术社区  · 15 年前

    我正在努力改进一些代码,但我想不出更好的方法来实现它目前的功能。本质上,我在外循环,将项目数除以我要选择的数量,然后在该循环中,我根据项目数的内循环选择项目,我需要创建一个项目,通过outerloop值修改该项目,因此在下面的示例中,外循环两次(0,1),每个外循环两次内循环(0,1然后2,3)。

    有谁能找到一种更具可读性的方法来做这件事,或者不做两个循环的方法来做这件事?

    希望这有道理。谢谢。

    string xml = @"
    <MainItem>
     <Select>2</Select>
     <ItemArray>
       <Item>One</Item>
       <Item>Two</Item>
       <Item>Three</Item>
       <Item>Four</Item>
     </ItemArray>
    </MainItem>";
    
    var doc = XDocument.Parse(xml);
    

    这里的Select值告诉我有多少个条目创建了一个“object”,所以在这个例子中,2个条目是一个对象(可以是任意数量,但是条目的数量总是允许正确的对象数量),目前我正在做类似的事情

        List<List<XElement>> items = new List<List<XElement>>();
        for(int i = 0;i < (doc.Descendants("Item").Count() / (int)doc.Element("MainItem").Element("Select"));i++)
        {
          //this is one object
         var singleItem = new List<XElement>();
          for (int j = 0; j <  (int)doc.Element("MainItem").Element("Select"); j++)
         {
             var item =  doc.Descendants("Item").ElementAt(j + (i * (int)doc.Element("MainItem").Element("Select")));
             singleItem.Add(item);
         }
         items.Add(singleItem);
        }
    

    所以我们以一个包含两个项目的列表结束,每个项目包含两个元素(一个和两个一起,三个和四个一起) 所以。。

    ItemOne
     One
     Two
    ItemTwo
     Three
     Four
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Winston Smith    15 年前

    有一种简单的方法可以通过一个LINQ语句来实现。你可以分组 item index / batchSize

    int batchSize = (int)doc.Element("MainItem").Element("Select");
    var items = doc
                .Descendants("Item")
                .Select( (e, i) => new {i,e} )
                .GroupBy( g => g.i / batchSize )
                .Select( g => g.Select( gv => gv.e) )
                ;
    

    IEnumerable<IEnumerable<XElement>> ,在您描述的结构中。

        2
  •  2
  •   Amy B    15 年前
    public static IEnumerable<List<T>> Batch<T>(
      this IEnumerable<T> source,
      int batchAmount) 
    { 
      List<T> result = new List<T>(); 
      foreach(T t in source) 
      { 
        result.Add(t); 
        if (result.Count == batchSize) 
        { 
          yield return result; 
          result = new List<T>(); 
        } 
      } 
      if (result.Any()) 
      { 
        yield return result; 
      } 
    } 
    

    int batchAmount = (int)doc.Element("MainItem").Element("Select"));
    
    List<List<XElement>> items = doc.Descendants("Item")
      .Batch(batchAmount)
      .ToList();