以下是一个简单的透视代码框架,用 C# 编写,可用于创建灵活的透视表:

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

namespace PivotFramework
{
    public class PivotTable
    {
        private readonly List<AggregationColumn> _aggregationColumns;
        private readonly List<PivotColumn> _pivotColumns;
        private readonly List<PivotRow> _pivotRows;
        private readonly List<SourceRow> _sourceRows;

        public PivotTable()
        {
            _aggregationColumns = new List<AggregationColumn>();
            _pivotColumns = new List<PivotColumn>();
            _pivotRows = new List<PivotRow>();
            _sourceRows = new List<SourceRow>();
        }

        public void AddAggregationColumn(string columnName, Func<IEnumerable<object>, object> aggregationFunction)
        {
            _aggregationColumns.Add(new AggregationColumn(columnName, aggregationFunction));
        }

        public void AddPivotColumn(string columnName, Func<object, object> pivotFunction)
        {
            _pivotColumns.Add(new PivotColumn(columnName, pivotFunction));
        }

        public void AddPivotRow(string columnName, Func<object, object> pivotFunction)
        {
            _pivotRows.Add(new PivotRow(columnName, pivotFunction));
        }

        public void AddSourceRow(params object[] values)
        {
            _sourceRows.Add(new SourceRow(values));
        }

        public IEnumerable<PivotResultRow> Execute()
        {
            var groupedData = _sourceRows
                .GroupBy(sr => new { PivotRows = GetPivotRowValues(sr), PivotColumns = GetPivotColumnValues(sr) });

            foreach (var group in groupedData)
            {
                var pivotResultRow = new PivotResultRow();

                foreach (var pivotColumn in _pivotColumns)
                {
                    pivotResultRow[pivotColumn.ColumnName] = pivotColumn.PivotFunction(group.Key.PivotColumns);
                }

                foreach (var aggregationColumn in _aggregationColumns)
                {
                    pivotResultRow[aggregationColumn.ColumnName] = aggregationColumn.AggregationFunction(group.Select(sr => sr.Values[aggregationColumn.ColumnName]));
                }

                yield return pivotResultRow;
            }
        }

        private IEnumerable<object> GetPivotColumnValues(SourceRow sourceRow)
        {
            return _pivotColumns.Select(pc => pc.PivotFunction(sourceRow.Values[pc.ColumnName]));
        }

        private IEnumerable<object> GetPivotRowValues(SourceRow sourceRow)
        {
            return _pivotRows.Select(pr => pr.PivotFunction(sourceRow.Values[pr.ColumnName]));
        }
    }

    public class AggregationColumn
    {
        public AggregationColumn(string columnName, Func<IEnumerable<object>, object> aggregationFunction)
        {
            ColumnName = columnName;
            AggregationFunction = aggregationFunction;
        }

        public string ColumnName { get; }
        public Func<IEnumerable<object>, object> AggregationFunction { get; }
    }

    public class SourceRow
    {
        public SourceRow(params object[] values)
        {
            Values = values;
        }

        public object[] Values { get; }
    }

    public class PivotColumn
    {
        public PivotColumn(string columnName, Func<object, object> pivotFunction)
        {
            ColumnName = columnName;
            PivotFunction = pivotFunction;
        }

        public string ColumnName { get; }
        public Func<object, object> PivotFunction { get; }
    }

    public class PivotRow
    {
        public PivotRow(string columnName, Func<object, object> pivotFunction)
        {
            ColumnName = columnName;
            PivotFunction = pivotFunction;
        }

        public string ColumnName { get; }
        public Func<object, object> PivotFunction { get; }
    }

    public class PivotResultRow
    {
        private readonly Dictionary<string, object> _values;

        public PivotResultRow()
        {
            _values = new Dictionary<string, object>();
        }

        public object this[string columnName]
        {
            get { return _values[columnName]; }
            set { _values[columnName] = value; }
        }
    }
}

该框架使用 AddAggregationColumnAddPivotColumnAddPivotRow 方法定义聚合列、行列,并使用 AddSourceRow 添加数据源。Execute 方法返回一个包含聚合结果的 IEnumerable<PivotResultRow>

例如,可以使用以下代码创建透视表,将数据按地区和产品分组,并计算每个分组的总销售额:

var pivotTable = new PivotTable();

pivotTable.AddPivotColumn('地区', x => x);
pivotTable.AddPivotRow('产品', x => x);
pivotTable.AddAggregationColumn('总销售额', values => values.Sum());

pivotTable.AddSourceRow('北美', '手机', 1000);
// 添加更多数据源...

var results = pivotTable.Execute();

foreach (var result in results)
{
    Console.WriteLine($'地区: {result['地区']}, 产品: {result['产品']}, 总销售额: {result['总销售额']}');
}

该框架提供了灵活的透视表构建方式,可用于各种数据分析和展示场景。


原文地址: https://www.cveoy.top/t/topic/ol55 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录