Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ合并两个列表(复合键上的完全外部联接)_C#_Linq - Fatal编程技术网

C# LINQ合并两个列表(复合键上的完全外部联接)

C# LINQ合并两个列表(复合键上的完全外部联接),c#,linq,C#,Linq,我有两张单子 IEnumerable<Citrus> grapefruit = citrusList.Where(x => x.IsSmall == false); IEnumerable<Citrus> tangerines = citrusList.Where(x => x.IsSmall == true); 但我相信有更好的办法。我想基本上做一个完整的外部连接(把所有的葡萄柚和橘子结合起来,但把橘子从交叉处弄出来)。我的最终目标是有一个包装容器,里

我有两张单子

 IEnumerable<Citrus> grapefruit = citrusList.Where(x => x.IsSmall == false);
 IEnumerable<Citrus> tangerines = citrusList.Where(x => x.IsSmall == true);
但我相信有更好的办法。我想基本上做一个完整的外部连接(把所有的葡萄柚和橘子结合起来,但把橘子从交叉处弄出来)。我的最终目标是有一个包装容器,里面有一些葡萄柚,一些橘子和一些橘子。我相信在LINQ中有一种更优雅的方式可以做到这一点

…但我无法从和中找出它,它不完全是一个联盟,因为我正在修改交叉成员(http://msdn.microsoft.com/en-us/library/bb341731.aspx)


帮个小忙

实际上,听起来你需要一个内部连接,而不是外部连接。嵌套for循环实际上执行的是内部联接的等效操作。无论如何:

grapefruit
 .Join(
  tangerines,
  x => new { Color = x.Color, Flavor = x.Flavor, Texture = x.Texture, State = x.State },
  x => new { Color = x.Color, Flavor = x.Flavor, Texture = x.Texture, State = x.State },
  (o,i) => new Tangelo(o.Color, o.Flavor, o.Texture, o.State, "A tangelo", new Decimal(0.75))
 ).Map(x => container.Add(x));
其中,“Map”是IEnumerables的“ForEach”式扩展方法:

public static void Map<T>(this IEnumerable<T> source, Action<T> func)
{
    foreach (T i in source)
        func(i);
}

然后,您可以使用David B答案中的map方法或AddRange方法将它们添加到容器中。

您不需要完全的外部连接,否则您将制作一些不含葡萄柚的桔子和一些不含桔子的桔子

这是一个内部连接

List<Tangelo> tangelos = (
from fruit in grapefruit
join fruitToo in tangerines
  on new {fruit.Flavor, fruit.Color, fruit.Flavor, fruit.State}
  equals new {fruitToo.Flavor, fruitToo.Color, fruitToo.Flavor, fruitToo.State}
select new Tangelo(fruit.Color, fruit.Flavor, fruit.Texture, fruit.State,
  "A tangelo", new Decimal(0.75))
).ToList()

我认为这样做很有效:

var cs = from c in citrusList
         group c by new { c.Color, c.Flavor, c.Texture, c.State } into gcs
         let gs = gcs.Where(gc => gc.IsSmall == false)
         let ts = gcs.Where(gc => gc.IsSmall == true)
         let Tangelos = gs
            .Zip(ts, (g, t) =>
                new Tangelo(g.Color, g.Flavor, g.Texture, g.State,
                    "A tangelo", new Decimal(0.75)))
         select new
         {
             gcs.Key,
             Grapefruit = gs.Skip(Tangelos.Count()),
             Tangerines = ts.Skip(Tangelos.Count()),
             Tangelos,
         };

var container = new PackingContainer();

container.AddRange(from c in cs
                   from f in c.Grapefruit
                       .Concat(c.Tangerines)
                       .Concat(c.Tangelos.Cast<Citrus>())
                   select f);
var cs=来自citrusList中的c
c组通过新的{c.颜色,c.风味,c.质地,c.状态}进入gcs
设gs=gcs.Where(gc=>gc.IsSmall==false)
设ts=gcs.Where(gc=>gc.IsSmall==true)
设Tangelos=gs
.Zip(ts,(g,t)=>
新探戈乐(g.颜色、g.风味、g.质地、g.状态、,
“探戈舞曲”,新十进制(0.75)
选择新的
{
地面军事系统键,
葡萄柚=gs.Skip(Tangelos.Count()),
Tangerines=ts.Skip(Tangelos.Count()),
坦格洛斯,
};
var container=新的打包容器();
container.AddRange(从c到cs
从f到c.葡萄柚
香菇
.Concat(c.Tangelos.Cast())
选择f);

内部联接只返回可制成桔子的葡萄柚和橘子。()我要所有的葡萄柚和橘子,但我要所有符合规定标准的葡萄柚和橘子都变成橘子。在我看来,这似乎是一个完整的外部连接()似乎是一个不错的答案,尽管在这种复杂程度上,我认为我最好还是坚持使用foreach循环。看起来这对LINQ来说并不是一个简单的例子。我想要葡萄柚不带橘子,橘子不带橘子,但橘子不带一些葡萄柚和橘子的交叉点。关于1:M匹配的观点很好,我想要葡萄柚和橘子之间的1:1映射,它们被制成橘子?可能但是很乱。这并不是我想要的“在LINQ中做这件事更优雅的方式”。Zip看起来像一个扩展函数,有多个let和where…我很想看看与基本嵌套foreach循环的性能比较。
List<Tangelo> tangelos = (
from fruit in grapefruit
join fruitToo in tangerines
  on new {fruit.Flavor, fruit.Color, fruit.Flavor, fruit.State}
  equals new {fruitToo.Flavor, fruitToo.Color, fruitToo.Flavor, fruitToo.State}
select new Tangelo(fruit.Color, fruit.Flavor, fruit.Texture, fruit.State,
  "A tangelo", new Decimal(0.75))
).ToList()
List<Tangelo> tangelos = (
from fruit in tangerines
where grapefruit.Any(fruitToo => 
  new {fruit.Flavor, fruit.Color, fruit.Flavor, fruit.State}
  == new {fruitToo.Flavor, fruitToo.Color, fruitToo.Flavor, fruitToo.State})
select new Tangelo(fruit.Color, fruit.Flavor, fruit.Texture, fruit.State,
  "A tangelo", new Decimal(0.75))
).ToList()
container.AddRange(tangelos);
var cs = from c in citrusList
         group c by new { c.Color, c.Flavor, c.Texture, c.State } into gcs
         let gs = gcs.Where(gc => gc.IsSmall == false)
         let ts = gcs.Where(gc => gc.IsSmall == true)
         let Tangelos = gs
            .Zip(ts, (g, t) =>
                new Tangelo(g.Color, g.Flavor, g.Texture, g.State,
                    "A tangelo", new Decimal(0.75)))
         select new
         {
             gcs.Key,
             Grapefruit = gs.Skip(Tangelos.Count()),
             Tangerines = ts.Skip(Tangelos.Count()),
             Tangelos,
         };

var container = new PackingContainer();

container.AddRange(from c in cs
                   from f in c.Grapefruit
                       .Concat(c.Tangerines)
                       .Concat(c.Tangelos.Cast<Citrus>())
                   select f);