Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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# 列表<;T>;。使用带2个参数的Lambda表达式进行排序_C#_Sorting_Lambda - Fatal编程技术网

C# 列表<;T>;。使用带2个参数的Lambda表达式进行排序

C# 列表<;T>;。使用带2个参数的Lambda表达式进行排序,c#,sorting,lambda,C#,Sorting,Lambda,我正在深入阅读C#,试图更好地理解这门语言。我以前使用过简单的lambda表达式,只使用了一个参数,并且对它们很熟悉。我正在努力解决的部分是films.Sort((f1,f2)=>f1.Name.CompareTo(f2.Name))对列表进行排序。根据我所能理解的,当我尝试向lambda表达式添加f3时,lambda表达式的计算结果为IComparer。被调用的方法确定项目顺序 第二个参数让我想说,它比较列表中的第n个和第n+1个film,并从0到films.Count-1。这是正确的吗?如果

我正在深入阅读C#,试图更好地理解这门语言。我以前使用过简单的lambda表达式,只使用了一个参数,并且对它们很熟悉。我正在努力解决的部分是
films.Sort((f1,f2)=>f1.Name.CompareTo(f2.Name))
对列表进行排序。根据我所能理解的,当我尝试向lambda表达式添加
f3
时,lambda表达式的计算结果为
IComparer
。被调用的方法确定项目顺序

第二个参数让我想说,它比较列表中的第n个和第n+1个
film
,并从0到
films.Count-1
。这是正确的吗?如果没有,我在哪一部分错了。我不想避免错误的假设和意外的错误

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var films = GetFilms();

        Action<Film> print = film => Console.WriteLine("Name={0}, Year={1}", film.Name, film.Year);

        Console.WriteLine("All films");
        films.ForEach(print);

        Console.WriteLine();
        Console.WriteLine("Old films");
        films.FindAll(film => film.Year < 1960).ForEach(print);

        Console.WriteLine();
        Console.WriteLine("Sorted films");
        films.Sort((f1, f2) => f1.Name.CompareTo(f2.Name));
        films.ForEach(print);
    }

    class Film
    {
        public string Name { get; set; }
        public int Year { get; set; }
    }

    static List<Film> GetFilms()
    {
        return new List<Film>
        {
            new Film { Name = "Jaws", Year = 1975 },
            new Film { Name = "Singing in the Rain", Year = 1952 },
            new Film { Name = "Some like it Hot", Year = 1959 },
            new Film { Name = "The Wizard of Oz", Year = 1939 },
            new Film { Name = "It's a Wonderful Life", Year = 1946 },
            new Film { Name = "American Beauty", Year = 1999 },
            new Film { Name = "High Fidelity", Year = 2000 },
            new Film { Name = "The Usual Suspects", Year = 1995 }
        };
    }
}
使用系统;
使用System.Collections.Generic;
公共课程
{
公共静态void Main()
{
var films=GetFilms();
Action print=film=>Console.WriteLine(“Name={0},Year={1}”,film.Name,film.Year);
控制台。WriteLine(“所有电影”);
电影。ForEach(印刷版);
Console.WriteLine();
控制台。WriteLine(“旧电影”);
菲林.芬德尔(菲林=>菲林.年份<1960年).ForEach(印刷版);
Console.WriteLine();
控制台。WriteLine(“分类电影”);
films.Sort((f1,f2)=>f1.Name.CompareTo(f2.Name));
电影。ForEach(印刷版);
}
班级电影
{
公共字符串名称{get;set;}
公共整数年{get;set;}
}
静态列表GetFilms()
{
返回新列表
{
新电影{Name=“Jaws”,年份=1975},
新电影{Name=“在雨中歌唱”,年份=1952},
新电影{Name=“Some like it Hot”,Year=1959},
新电影{Name=“绿野仙踪”,年份=1939},
新电影{Name=“这是美好的生活”,年份=1946},
新电影{Name=“American Beauty”,1999年},
新电影{Name=“High Fidelity”,年份=2000},
新电影{Name=“通常的嫌疑犯”,年份=1995}
};
}
}

您无法从方法签名中判断参数将被使用多少次。我可以编写一个从未调用其参数的方法
Foo(Func)

但是,由于这是一种排序方法,因此仅在列表上迭代一次是不够的。有很多不同的排序算法,但它们倾向于使用
O(n log(n))
比较。换句话说,将排序列表的长度加倍将导致对lambda函数的调用增加一倍以上

如果您想查看它运行时实际发生的情况,请添加一些日志

films.Sort((f1, f2) => 
{
    Console.WriteLine("Comparing ${f1.Name} to ${f2.Name}");
    return f1.Name.CompareTo(f2.Name);
});

您无法从方法签名判断参数将被使用多少次。我可以编写一个从未调用其参数的方法
Foo(Func)

但是,由于这是一种排序方法,因此仅在列表上迭代一次是不够的。有很多不同的排序算法,但它们倾向于使用
O(n log(n))
比较。换句话说,将排序列表的长度加倍将导致对lambda函数的调用增加一倍以上

如果您想查看它运行时实际发生的情况,请添加一些日志

films.Sort((f1, f2) => 
{
    Console.WriteLine("Comparing ${f1.Name} to ${f2.Name}");
    return f1.Name.CompareTo(f2.Name);
});

实际上,您可以使用LINQ对实现
IEnumerable
接口的任何类型的元素进行排序,如
List
类型:

//这将按电影名称排序。
var结果1=
电影
.OrderBy(film=>film.Name)
.ToList();
//这将以降序和降序的方式在每年的第一次订购电影
//然后按名称升序排列。
var结果2=
电影
.OrderByDescending(film=>film.Year)
.ThenBy(film=>film.Name)
.ToList();
您还可以使用
ThenByDescending()
方法,如果需要,还可以使用这些方法创建更长的链


这里的问题是,您应该在lambda表达式中一次只选择一个属性。

实际上,您可以使用LINQ对实现
IEnumerable
接口的任何类型的元素进行排序,如
List
type:

//这将按电影名称排序。
var结果1=
电影
.OrderBy(film=>film.Name)
.ToList();
//这将以降序和降序的方式在每年的第一次订购电影
//然后按名称升序排列。
var结果2=
电影
.OrderByDescending(film=>film.Year)
.ThenBy(film=>film.Name)
.ToList();
您还可以使用
ThenByDescending()
方法,如果需要,还可以使用这些方法创建更长的链


这里的问题是,您应该在lambda表达式中一次只选择一个属性。

按照您的建议,发现在本例中,它使用的是选择排序。看到我可以在
=>
操作符之后使用
{…}
是有意义的。非常感谢。@IvenBach很高兴它成功了!使用大括号时会有细微的差别;您必须
返回
最终值。按照您的建议,发现在本例中,它使用了选择排序。看到我可以在
=>
操作符之后使用
{…}
是有意义的。非常感谢。@IvenBach很高兴它成功了!使用大括号时会有细微的差别;您必须
返回
最终值。