문제

.NET의 LINQ를 사용하여 계층 적 데이터를 합산 할 수 있습니까?

내 데이터 클래스는 다음과 같습니다.

class Node
{
    public decimal Amount;
    public IEnumerable<Node> Children { get; set; }
}

그래서 나는 약간의 데이터가 다음과 같이 보일 것입니다. 그러나 나무는 물론 임의로 깊을 수 있습니다.

var amounts = new Node
{
    Amount = 10;
    Children = new[]
    {
        new Node
        {
            Amount = 20
        },
        new Node
        {
            Amount = 30
        }
    }
};

모든 금액을 합계하고 하나의 간단한 LINQ 쿼리로 결과 60을 얻을 수 있습니까?

도움이 되었습니까?

해결책

기술적으로 당신 ~할 수 있다 재귀 람다 표현을 작성하십시오, 그러나 시도하려면 미쳤거나 미친 듯이 밝아 야합니다 (나는 어느 것을 알아 내지 못했습니다). 그러나 당신은 속임수를 만들 수 있습니다 :

    Func<Node, decimal> nodeSum = null;
    nodeSum = node => {
        decimal result = node.Amount;
        if (node.Children != null) {
            result = result + node.Children.Sum(nodeSum);
        }
        return result;
    };
    var value = nodeSum(amounts);

다른 팁

고차 기능으로 수행 할 수 있습니다.

Func<Node, decimal> summer = null;
summer = node => node.Amount + 
                 (node.Children == null ? 0m : node.Children.Sum(summer));
decimal total = summer(amounts);

Node.children이 결코 null이되지 않도록 할 수 있다면 여름은 더 간단 할 수 있습니다.

summer = node => node.Amount + node.Children.Sum(summer);

또는 Null Coalescing 연산자를 사용할 수 있습니다.

summer = node => node.Amount + 
                 (node.Children ?? Enumerable.Empty<Node>()).Sum(summer);

물론 이것을 대신 별도의 방법에 넣을 수 있습니다.

static decimal SumNodes(Node node)
{
    return node.Amount + 
        (node.Children ?? Enumerable.Empty<Node>())
            .Sum((Func<Node, decimal>)SumNodes);
}

여기서 추악함은 방법 그룹 변환의 모호성 때문입니다. 방법 그룹은 유형의 추론에서 많은 사랑을 얻지 못합니다.

그런 다음 전화하십시오 SumNodes(amount). 많은 옵션 :)

첫 번째 형식의 전체 예 :

using System;
using System.Collections.Generic;
using System.Linq;

class Node
{
    public decimal Amount;
    public IEnumerable<Node> Children { get; set; }
}

public class Test
{
    static void Main()
    {
        var amounts = new Node {
            Amount = 10, Children = new[] {
                new Node { Amount = 20 },
                new Node { Amount = 30 }
            }
        };

        Func<Node, decimal> summer = null;
        summer = node => node.Amount + 
            (node.Children == null ? 0m : node.Children.Sum(summer));

        decimal total = summer(amounts);

        Console.WriteLine(total);
    }
}

이 중 하나라도 "간단한"LINQ 쿼리라고 부를지 모르겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top