简体   繁体   English

LINQ .select之后返回List &lt;{int,double}&gt;两个值,但我需要List <int> 只有一个值

[英]LINQ returns List<{int,double}> two values after .selected but I need List<int> with one value only

I have got this assignment. 我有这个任务。 I need to create method which works with JSON data in this form: 我需要创建以这种形式使用JSON数据的方法:

On input N, what is top N of movies? 在输入N上,电影的前N个是什么? The score of a movie is its average rate 电影的分数是其平均评分

So I have a JSONfile with 5 mil. 所以我有一个500万的JSONfile。 movies inside. 里面的电影。 Each row looks like this: 每行看起来像这样:

{ Reviewer:1, Movie:1535440, Grade:1, Date:'2005-08-18'},
{ Reviewer:1, Movie:1666666, Grade:2, Date:'2006-09-20'},
{ Reviewer:2, Movie:1535440, Grade:3, Date:'2008-05-10'},
{ Reviewer:3, Movie:1535440, Grade:5, Date:'2008-05-11'},

This file is deserialized and then saved as a IEnumerable. 该文件被反序列化,然后另存为IEnumerable。 And then I wanted to create a method, which returns List<int> where int is MovieId. 然后我想创建一个方法,该方法返回List<int> ,其中int是MovieId。 Movies in the list are ordered descending and the amount of "top" movies is specified as a parameter of the method. 列表中的电影按降序排列,并且“顶部”电影的数量被指定为该方法的参数。

My method looks like this: 我的方法如下所示:

public List<int> GetSpecificAmountOfBestMovies(int amountOfMovies)
{
    var moviesAndAverageGradeSortedList = _deserializator.RatingCollection()
        .GroupBy(movieId => movieId.Movie)
        .Select(group => new
        {
            Key = group.Key, 
            Average = group.Average(g => g.Grade)
        })
        .OrderByDescending(a => a.Average)
        .Take(amountOfMovies)
        .ToList();

    var moviesSortedList = new List<int>();
    foreach (var movie in moviesAndAverageGradeSortedList)
    {
        var key = movie.Key;
        moviesSortedList.Add(key);
    }
    return moviesSortedList;
}

So moviesAndAverageGradeSortedList returns List<{int,double}> because of the .select method. 因此List<{int,double}>由于.select方法List<{int,double}> moviesAndAverageGradeSortedList返回List<{int,double}> So I could not return this value as this method is type of List<int> because I want only movieIds not their average grades. 因此,我无法返回此值,因为此方法是List<int>类型,因为我只希望movieIds而不是其平均成绩。

So I created a new List<int> and then foreach loop which go through the moviesAndAverageGradeSortedList and saves only Keys from that List. 因此,我创建了一个新的List<int> ,然后创建了foreach循环,遍历了moviesAndAverageGradeSortedList并仅保存了该列表中的键。

I think this solution is not correct because foreach loop can be then very slow when I put big number as a parameter. 我认为此解决方案是不正确的,因为当我将大数字作为参数时,foreach循环可能会非常缓慢。 Does somebody know, how can I get "Keys" ( movieIds ) from the first list and therefore avoid creating another List<int> and foreach loop? 有人知道,如何从第一个列表中获取“键”( movieIds ),从而避免创建另一个List<int>和foreach循环?

I will be thankful for every solution. 我将为每一个解决方案而感激。

You can avoid the second list creation by just adding another .Select after the ordering. 您可以通过在订购后添加另一个.Select来避免第二个列表的创建。 Also to make it all a bit cleaner you could: 另外,为了使它更整洁,您可以:

return _deserializator.RatingCollection()
            .GroupBy(i => i.Movie)
            .OrderByDescending(g => g.Average(i => i.Grade))
            .Select(g => g.Key)
            .Take(amountOfMovies)
            .ToList();

Note that this won't really improve performance much (if at all) because even in your original implementation the creation of the second list is done only on the subset of the first n items. 请注意,这并不能真正提高性能(如果有的话),因为即使在您的原始实现中,第二个列表的创建也仅在前n个项目的子集上完成。 The expensive operations are the ordering by the averages of the group and that you want to perform on all items in the json file, regardless to the number of item you want to return 昂贵的操作是按组的平均值进行排序,并且您想要对json文件中的所有项目执行操作,而不管您要返回的项目数量如何

You could add another select after you have ordered the list by average 您可以按平均顺序订购列表后添加另一个选择

var moviesAndAverageGradeSortedList = _deserializator.RatingCollection()
            .GroupBy(movieId => movieId.Movie)
            .Select(group => new
            {
                Key = group.Key, 
                Average = group.Average(g => g.Grade)
            })
            .OrderByDescending(a => a.Average)
            .Take(amountOfMovies)
            .Select(s=> s.Key)
            .ToList();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM