【问题标题】:Combine list<object> and list<otherobject> into single flat list将 list<object> 和 list<otherobject> 组合成单个平面列表
【发布时间】:2014-06-27 14:49:18
【问题描述】:

我有一个对象,它具有另一个对象列表的成员。 即:

public class ObjA
{
    public int Id { get; set; }
    Other members....
    public List<ObjB> ObjBs{ get; set; }
}

public class ObjB
{
  public int Id { get; set; }
  Other members...
}

我目前在 foreach 中填充 ObjA 对象,然后在 foreach 循环中调用另一个 foreach 填充 ObjB 列表并将其添加到 ObjA 中的 ObjBs 成员中。

理想情况下,我想要一个 ObjA 的平面列表,所有相关的 ObjB(按 ID)都附加到列表中。这可能吗,我的页面中有所有 ObjA 和所有 ObjB 的临时列表,只是不确定如何将它们加入动态单个平面列表?

希望这有意义吗?

【问题讨论】:

  • 你说的是LINQ的SelectMany()Concat()函数吗?
  • 如您所见,ObjB 和 ObjA 之间存在多对一的关系——这是正确的吗?也就是说,是否有许多 ObjB 与单个 ObjA 相关联?如果是这样,那么转换为单个列表没有意义。
  • 嗨,Hogan,你说得对,这是一个 -> 从 ObjA 到 ObjB 的多个。我试图让一个列表说 (item[0] = objA + ObjB + ObjB + ObjB, item[1] = objA + ObjB + ObjB + ObjB 等),其中 objA + ObjB 有一个共同的 ID。跨度>

标签: c# linq list


【解决方案1】:

好吧,它必须只是一个List&lt;object&gt;,但这应该可以工作:

// Flat list of ObjB
var referenced = listA.SelectMany(x => x.ObjBs);

// Concatenate listA with the flat list of ObjB
var flat = listA.Concat<object>(referenced).ToList();

【讨论】:

    【解决方案2】:

    编辑

    根据您的评论,看起来您想要:

    IEnumerable<object[]> output = listA.Select(a => (new []{a}).Cast<object>()
                                                                .Concat(a.ObjBs) 
                                                                .ToArray());
    

    var output = listA.Select(a => (new [] {new {a.Id}})
                                              .Concat(a.ObjBs.Select(b => new {b.Id}));
                                 );
    

    原答案

    这是一个单行,虽然它不是您指定的顺序(如果重要的话):

    IEnumerable<object> output = listA.SelectMany(a => a.ObjBs
                                                        .Cast<object>()
                                                        .Concat(new [] {a}) );
    

    或者如果你想创建一个具有公共属性的匿名类型:

    var output = listA.SelectMany(a => a.ObjBs.Select(b => new {b.Id})
                                              .Concat(new [] {new {a.Id}})
                                 );
    

    这样您至少可以访问公共属性而无需强制转换或反射。

    【讨论】:

    • 完美:IEnumerable output = Exams.Select(e => (new []{e}).Cast() .Concat(e.answers) .ToArray( ));
    • 现在是否可以从列表中的第一项中删除答案?即它返回考试对象以及第一个项目[0] [0]中的答案列表,然后项目[0] [1]是第一个答案对象,项目[0] [2]是第二个答案,这就是我想要但希望答案列表不再包含在 item[0][0] 中,希望这有意义吗?
    • @user3783297 您必须修改原始对象(您可能不想这样做)或创建一个新对象将所有数据除了答案。跨度>
    • 因此,如果我有第二个没有答案的考试对象,即examWithoutAnswers 具有与考试完全相同的数据但没有答案。您的 Linq 示例将如何使用它?再次感谢您的帮助:)
    【解决方案3】:

    如果您希望它们按第一个 A 然后它的 Bs 的顺序排列,第二个 A 然后它是 Bs 等等。

    var flat = listA.SelectMany(a => new List<object> {a}.Concat(a.ObjBs)).ToList();
    

    必须是List&lt;object&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多