在LINQ中解压缩压缩列表

时间:2014-10-14 09:38:42

标签: c# sorting

在一个规格严格的界面中,我们有

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).

但现在我不知道如何再次解压缩列表...

4 个答案:

答案 0 :(得分:5)

int[] userIdList = zipped.Select(x => x.id).ToArray();
string[] userNameList = zipped.Select(x => x.name).ToArray();

答案 1 :(得分:1)

输入:

 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代码那样分配新的数组,而只是重新排序现有数组中的项目,这是更多高效。

答案 2 :(得分:0)

如果集合是列表类型,则可以解压缩。您可以编写自己的解压缩扩展方法来实现此目的:

 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)

答案 3 :(得分:0)

我想要类似Scala unzip()之类的东西,所以我使用了@zafar的the solution

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));
}