在LINQ中解压缩列表
本文关键字:列表 解压缩 LINQ | 更新日期: 2023-09-27 18:26:23
在规格不好的接口中,我们有
int[] userIdList; // ids of all users to display
string[] userNameList; // names of all users to display
限制条件是userIdList[i]始终包含名为userNameList[i]的用户的ID。
新的要求是按名称对用户进行排序:我将接受这两个列表,按名称排序,并返回两个仍然存在上述限制的列表。
当然,我可以自己实现排序函数,但我认为单行linq语句可以做得更好?我上了
userNameList.Zip(userIdList, (name, id) => new {name, id}).OrderBy(a=>a.name).
但现在我不知道如何再次解压缩列表。。。
int[] userIdList = zipped.Select(x => x.id).ToArray();
string[] userNameList = zipped.Select(x => x.name).ToArray();
对于输入:
int[] userIdList = new []{ 1,5,3,6 }; // ids of all users to display
string[] userNameList = new []{ "Farix", "Doubles", "Rogue", "Splinter" }; // names of all users to display
你可以做:
Array.Sort(userNameList, userIdList);
然后,您将获得与LINQ代码完全相同的结果,但使用一个更简单的表达式,该表达式不会像LINQ代码中那样分配新的数组,而只是重新排序现有数组中的项,这样效率高得多。
如果集合是列表类型,则可以解压缩。您可以编写自己的解压缩扩展方法来实现这一点:
public static class ListExtensions
{
public static void Unzip<T, T1, T2>(this IList<T> source, Func<T, T1> firstSelector, Func<T, T2> secondSelector,
out IEnumerable<T1> first, out IEnumerable<T2> second)
{
first = source.Select(firstSelector);
second = source.Select(secondSelector);
}
}
用法:
enumerableEntitiesToUnzip.ToList().Unzip(e=>e.Prop1,e=>e.Prop2, out var first, out var second)
我想要类似Scala unzip()
的东西,所以我使用了@zafar 的解决方案
public static class ListExtensions
{
public static (IEnumerable<T1>, IEnumerable<T2>) Unzip<T1, T2>(
this IEnumerable<(T1, T2)> source
) => source.Unzip(tp => tp.Item1, tp => tp.Item2);
public static (IEnumerable<T1>, IEnumerable<T2>) Unzip<T1, T2>(
this IEnumerable<(T1, T2)> source,
Func<(T1, T2), T1> f1,
Func<(T1, T2), T2> f2
) => (source.Select(f1), source.Select(f2));
}