似乎我错过了一些微不足道的东西。
无论如何,这里是:
var order = new[]{1,3,2};
var foos = new[]{new Foo{Id=1}, new Foo{Id=2}, new Foo{Id=3}};
如何使用Linq按顺序数组对foos进行排序?
期望的结果:
foos == new[]{new Foo{Id=1}, new Foo{Id=3}, new Foo{Id=2}};
修改
订单包含Foo ID。对不起,我没有提到。有时候提问问题比回答问题更难。 :)
答案 0 :(得分:4)
这是你想要做的吗?
foos.OrderBy(f => order[f.Id-1]);
如果你现在预先输出,打印ID,你会得到:1,3,2
答案 1 :(得分:3)
from o in order.Select((o, i) => new { o, i })
join f in foos on o.o equals f.Id
orderby o.i
select f;
答案 2 :(得分:3)
好的,这个问题对我来说似乎并不完全 >
正确? 那将是: 您需要 可以用点符号表示为:
var orderedFoos = from orderedId in order
join foo in foos on orderedId equals foo.Id into groups
select groups.Single();
join ... into
来验证foos
中没有任何丢失或重复的ID。但是,它不会检测您是否在order
中丢失或重复了ID。如果您知道所有内容都是正确的(即foos
中的每个条目order
中只有一个条目,反之亦然),那么简单的加入就可以了:var orderedFoos = from orderedId in order
join foo in foos on orderedId equals foo.Id
select foo;
var orderedFoos = order.Join(foos, order => order, foo => foo.ID, (o, f) => f);
答案 3 :(得分:1)
如果我有很多要做的话,我可能会使用Dictionary<int,int>
id / ordering对来进行订单查找O(1)。请注意,您还需要处理订单中缺少值的情况 - 我选择将它们移到最后。
var order = new Dictionary<int,int>();
order.Add( 1, 1 );
order.Add( 2, 3 );
order.Add( 3, 2 );
var orderedFoos = foos.OrderBy( f => order.Contains(f.Id) ? order[f.Id] : int.MaxValue );
答案 4 :(得分:1)
您可以使用嵌套查询执行此操作,但使用O(n²)
效率非常低。
var result = order.Select(o => foos.Single(f => f.Id == o));
如果'order'可能包含'foos'中不存在的ID,则应使用SingleOrDefault()
。如果foos
可能包含重复的ID,则应使用First()
或FirstOrDefault()
。
var result = order
.Select(o => foos.FirstOrDefault(f => f.Id == o))
.Select(f => f != null);
甚至连接都可行,但我不确定它是否会保留订单。
var result = Enumerable.Join(order, foos, o => o, f => f.Id, (o, f) => f);
正如Jon所提到的,如果输入的形式与我的第一个建议所需的方式相同,则连接只能正常工作。
答案 5 :(得分:0)
var order = new[] { 1, 3, 2 };
var foos = new[] { new Foo { Id = 1 }, new Foo { Id = 2 }, new Foo { Id = 3 } };
var query = from o in order
join foo in foos on o equals foo.Id
select foo;
var foos2 = query.ToArray();