05
04
출처: 프로그래머스 코딩 테스트 연습
https://school.programmers.co.kr/learn/courses/30/lessons/42579

 

 

나의 풀이

public int[] solution(string[] genres, int[] plays) 
{
    var zipList = Enumerable.Range(0, genres.Length)
                            .Select(s => new{ index = s, genre = genres[s], play = plays[s]})
                            .ToList();

    List<string> genreRank = zipList.GroupBy(g => g.genre)
                                    .Select(s => new{ genre = s.Key, sum = s.Sum(t => t.play)} )
                                    .OrderByDescending(o => o.sum)
                                    .Select(s => s.genre)
                                    .ToList();

    var topTwoEnumerable = zipList.GroupBy(g => g.genre)
                        .OrderBy(o => genreRank.IndexOf(o.Key))
                        .Select(s => s.OrderByDescending(t => t.play).Take(2));

    var list = new List<int>();
    foreach(var x in topTwoEnumerable)
    {
        foreach(var member in x)
            list.Add(member.index);
    }

    return list.ToArray();
}

데이터 컨테이너 클래스를 만들어서 반복문 순회하면서 풀면 더 쉽지만

LINQ 연습 겸 무명 클래스로만 작성해 봤다.

 

핵심은 GroupBy로 쿼리 된 IGroup을 다시 LINQ를 사용하여 정렬하거나 Select를 사용하여 조작하는 것.

그룹으로 분류된 값들에 대해서 조작이 가능하다!

 

리팩토링

public int[] solution(string[] genres, int[] plays) 
{
    var zipList = Enumerable.Range(0, genres.Length)
                            .Select(i => new{ index = i, genre = genres[i], play = plays[i]})
                            .ToList();

    List<string> genreRank = zipList.GroupBy(g => g.genre)
                                    .OrderByDescending(g => g.Sum(t => t.play))
                                    .Select(g => g.Key)
                                    .ToList();

    var topTwoEnumerable = zipList.GroupBy(g => g.genre)
                                  .OrderBy(g => genreRank.IndexOf(g.Key))
                                  .Select(g => g.OrderByDescending(t => t.play).Take(2));

    return topTwoEnumerable.SelectMany(x => x).Select(x => x.index).ToArray();
}

 

 

COMMENT