Плагин кластеризации данных


using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using DynamicPluginData;
using System.Text.RegularExpressions;


namespace DatacolDynamicPluginNS
{
    public class DynamicPluginClass
    {
        static Dictionary<string, List<string>> ClasterizationRules = new Dictionary<string, List<string>>();
        static Dictionary<string, Dictionary<string, double>> SumsForClasters = new Dictionary<string, Dictionary<string, double>>();
        static Dictionary<string, int> ClasterCounts = new Dictionary<string, int>();

        static List<string> FieldsToAverage = new List<string>();//{"param1","param2"}
        
        static bool CalculateSumsAndAverages = true;

        public static DataTable preExportData(DataTable dataTable, ItemInfo itemInfo, GlobalInfo globalInfo)
        {
            dataTable.Columns.Add("claster");

            ClasterizationRules.Add("Some Claster Name",
                new List<string> { "token1", "token2" }
            );
            
            /*
            ClasterizationRules.Add
            (   
                "",
                new List<string> { "","" }
            );
            */
        
            foreach (string Claster in ClasterizationRules.Keys)
            {
                ClasterCounts.Add(Claster, 0);
            }
            
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                dataTable.Rows[i]["claster"] = String.Join(",", getClasters(dataTable.Rows[i][0].ToString()).ToArray());
            }

            if (CalculateSumsAndAverages)
            {
                dataTable.Columns.Add("count");

                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    if (String.IsNullOrEmpty(dataTable.Rows[i]["claster"].ToString())) continue;

                    foreach (DataColumn dc in dataTable.Columns)
                    {
                        addToSumsAveragesDictionary(dataTable.Rows[i]["claster"].ToString(), dc.ColumnName, dataTable.Rows[i][dc.ColumnName].ToString());
                    }
                }

                DataRow r = dataTable.NewRow();
                r[0] = "Total report on sums, averages and counts for clasters (added by Datacol)";

                dataTable.Rows.Add(dataTable.NewRow());
                dataTable.Rows.Add(r);

                foreach (string Claster in SumsForClasters.Keys)
                {
                    r = dataTable.NewRow();
                    r["claster"] = Claster;
                    if (ClasterCounts.ContainsKey(Claster))
                    r["count"] = ClasterCounts[Claster];

                    foreach (string Parameter in SumsForClasters[Claster].Keys)
                    {
                        if (ClasterCounts.ContainsKey(Claster) && ClasterCounts[Claster] > 0)
                        {
                            if (FieldsToAverage.Contains(Parameter))
                                r[Parameter] = (Math.Round(SumsForClasters[Claster][Parameter] / ClasterCounts[Claster])).ToString();
                            else
                                r[Parameter] = SumsForClasters[Claster][Parameter].ToString();
                        }
                    }
                    dataTable.Rows.Add(r);
                }
            }

            return dataTable;
        }

        static void addToSumsAveragesDictionary(string Claster, string DataFieldName, string Value)
        {
            double ValueDouble = 0;

            if (!Double.TryParse(Value, out ValueDouble)) return;

            if (!SumsForClasters.ContainsKey(Claster))
            {
                SumsForClasters.Add(Claster, new Dictionary<string, double>());
            }
            if (!SumsForClasters[Claster].ContainsKey(DataFieldName))
            {
                SumsForClasters[Claster].Add(DataFieldName, 0);
            }
            SumsForClasters[Claster][DataFieldName] += ValueDouble;
        }

        static List<string> getClasters(string str)
        {
            List<string> Clasters = new List<string>();

            
            
            foreach (string Claster in ClasterizationRules.Keys)
            {
                bool found = false;
                
                foreach (string Token in ClasterizationRules[Claster])
                {
                    try
                    {
                        if (Regex.IsMatch(str, Token, RegexOptions.Singleline | RegexOptions.IgnoreCase))
                        {
                            ClasterCounts[Claster]++;

                            Clasters.Add(Claster);
                            found = true;
                            break;
                        }
                    }
                    catch{}
                }
                if(found)break;
            }

            return Clasters;
        }
    }
}