Хобрук: Ваш путь к мастерству в программировании

Сводка наблюдаемой коллекции

У меня есть такие записи в наблюдаемой коллекции

ID Department salary joingdate 
1    .NET   5000  04/08/2011
2    .NET   6000  04/07/2011
3    JAVA   7000  04/08/2011
4    JAVA   8000  04/07/2011
5    .NET   9000  04/06/2011

теперь я хочу новую наблюдаемую коллекцию, например

Joingdate    .NET(Salary)  JAVA(Salary)
04/08/2011  5000        7000
04/07/2011  6000        8000
04/06/2011  9000        NULL

Как мне получить такую ​​наблюдаемую коллекцию?


  • Каков был бы результат, если бы был 6 .NET 9500 04/08/2011? 18.08.2011
  • Похоже, вы пытаетесь развернуть свои данные. 18.08.2011

Ответы:


1

Предполагая, что у вас есть следующая структура, которая напоминает вашу структуру:

public class Data1
{
    public int Id { get; set; }
    public String Dep { get; set; }
    public int Sal { get; set; }
    public String JoinDate { get; set; }
}

public class Data2
{
    public Data2()
    {
        Sal = new List<int>();
    }

    public List<int> Sal { get; set; }
    public String JoinDate { get; set; }

    public override string ToString()
    {
        return Sal.Aggregate(JoinDate, (current, s) => current + s.ToString());
    }
}

И следующие наблюдаемые коллекции:

public class Data1List : ObservableCollection<Data1>
{
    public Data1List()
    {
        Add(new Data1{ Id = 1, Dep = ".NET", Sal = 5000, JoinDate = "04/08/2011"});
        Add(new Data1{ Id = 2, Dep = ".NET", Sal = 6000, JoinDate = "04/07/2011"});
        Add(new Data1{ Id = 3, Dep = "JAVA", Sal = 7000, JoinDate = "04/08/2011"});
        Add(new Data1{ Id = 4, Dep = "JAVA", Sal = 8000, JoinDate = "04/07/2011"});
        Add(new Data1{ Id = 5, Dep = ".NET", Sal = 9000, JoinDate = "04/06/2011"});
    }
}

public class Data2List : ObservableCollection<Data2>
{
}

Вы можете попробовать этот код, чтобы решить вашу проблему или, по крайней мере, найти лучшее решение:

var l1 = new Data1List();
var l2 = new Data2List();

foreach (var items in l1.GroupBy(d => d.JoinDate))
{
    var d2 = new Data2 { JoinDate = items.Key };
    foreach (var item in items)
        d2.Sal.Add(item.Sal);
    l2.Add(d2);
}

Надеюсь, это поможет вам найти решение! :)

18.08.2011
  • Привет, Аббас, спасибо за вашу помощь. это действительно хорошее решение моей проблемы. 19.08.2011

  • 2

    Некоторое время назад я поигрался с вращением и ExpandoObject. Это, конечно, не производственный код.

    public static dynamic pivot(IEnumerable<Employee> rows)
    {
        IDictionary<string, Object> expando = new ExpandoObject();
        expando["Joindate"] = rows.First().Joindate;
        foreach (var row in rows)
        {
            expando[row.Department] = row.Salary;
        }
        return (dynamic)expando;
    }
    

    то каким-то способом где-нибудь

    var employees = new ObservableCollection<Employee>() { 
        new Employee() {ID=1, Department="NET", Salary=5000, Joindate=new DateTime(2011,04,08)},
        new Employee() {ID=2, Department="NET", Salary=6000, Joindate=new DateTime(2011,04,07)},
        new Employee() {ID=3, Department="JAVA", Salary=7000, Joindate=new DateTime(2011,04,08)},
        new Employee() {ID=4, Department="JAVA", Salary=8000, Joindate=new DateTime(2011,04,07)},
        new Employee() {ID=5, Department="NET", Salary=9000, Joindate=new DateTime(2011,04,06)}
    };
    
    var distinctDates = employees.Select(j => j.Joindate).Distinct().OrderByDescending(d => d);
    
    var salaryByDepartmentAndJoindate = distinctDates.Select(d => pivot(employees.Where(jd => jd.Joindate == d)));
    
    var result = new ObservableCollection<dynamic>(salaryByDepartmentAndJoindate);
    
    18.08.2011

    3

    Из-за того, как мои данные потребляются, мне нужны результаты в формате таблицы, а не в формате вложенных объектов. Таким образом, приведенный ниже код создает сводку из списка данных. Называется он так:

        // generate a pivot table
        var pivot = linqQueryResults.Pivot(
            rowKey => rowKey.DepartmentName,
            columnKey => columnKey.JoiningDate,
            value => value.Sum(emp => emp.Salary),
            "Department",
            new Dictionary<string, Func<GetComplianceForClientCurriculums_Result, object>>()
                {
                    {"DepartmentCode", extraRow => extraRow.DepartmentCode},
                    {"DepartmentManager", extraRow => extraRow.DeptManager}
                }
        );
    

    А метод расширения LINQ выглядит так:

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    
    namespace MyApplication.Extensions 
    {
    
        public static class LinqExtenions 
        {
            /// <summary>
            ///     Groups the elements of a sequence according to a specified firstKey selector 
            ///     function and rotates the unique values from the secondKey selector function into 
            ///     multiple values in the output, and performs aggregations. 
            /// </summary>
            /// <param name="source">The data source for the pivot</param>
            /// <param name="rowKeySelector">A function to derive the key for the rows</param>
            /// <param name="columnKeySelector">A function to derive the key for the columns</param>
            /// <param name="valueSelector">A function to calculate the contents of the intersection element. Usually this is an aggreation function</param>
            /// <param name="firstColumnName">The label to give the first column (row title)</param>
            /// <param name="additionalHeaderSelectors">An optional dictionary of additional rows to use as headers. Typically, this data should be consistent with the row selector since only the first match is taken.</param>
            /// <returns>A datatable pivoted from the IEnumerable source.</returns>
            /// <remarks>
            /// Based on concepts from this article: http://www.extensionmethod.net/Details.aspx?ID=147
            /// </remarks>
            public static DataTable Pivot<TSource, TRowKey, TColumnKey, TValue>(this IEnumerable<TSource> source, Func<TSource, TRowKey> rowKeySelector, Func<TSource, TColumnKey> columnKeySelector, Func<IEnumerable<TSource>, TValue> valueSelector, string firstColumnName = "", IDictionary<string, Func<TSource, object>> additionalHeaderSelectors = null)
            {
                var result = new DataTable();
    
                // determine what columns the datatable needs and build out it's schema
                result.Columns.Add(new DataColumn(firstColumnName));
                var columnNames = source.ToLookup(columnKeySelector);
                foreach (var columnName in columnNames)
                {
                    var newColumn = new DataColumn(columnName.Key.ToString());
                    result.Columns.Add(newColumn);
                }
    
                // if we have a 2nd header row, add it
                if (additionalHeaderSelectors != null)
                {
                    foreach (var additionalHeaderSelector in additionalHeaderSelectors)
                    {
                        var newRow = result.NewRow();
    
                        newRow[firstColumnName] = additionalHeaderSelector.Key;
    
                        foreach (var columnName in columnNames)
                        {
                            newRow[columnName.Key.ToString()] = additionalHeaderSelector.Value(columnName.FirstOrDefault());
                        }
    
                        result.Rows.Add(newRow);
                    }
                }
    
    
                // build value rows
                var rows = source.ToLookup(rowKeySelector);
                foreach (var row in rows)
                {
                    var newRow = result.NewRow();
    
                    // put the key into the first column
                    newRow[firstColumnName] = row.Key.ToString();
    
                    // get the values for each additional column
                    var columns = row.ToLookup(columnKeySelector);
                    foreach (var column in columns) 
                    {
                        newRow[column.Key.ToString()] = valueSelector(column);
                    }
    
                    result.Rows.Add(newRow);
                }
    
                return result;
            }
        }
    }
    
    07.12.2011
  • У меня это сработало. Можно ли изменить его, чтобы сводное значение было списком, а не агрегацией? Когда я использую нижеприведенное, я получаю представление списка в стиле ToString (). var pivot = people.Pivot( rowKey => rowKey.managerName ?? "null", columnKey => columnKey.company ?? "null", value => value.ToList(), "Manager", null ); 20.08.2013
  • Новые материалы

    Dall-E 2: недавние исследования показывают недостатки в искусстве, созданном искусственным интеллектом
    DALL-E 2 — это всеобщее внимание в индустрии искусственного интеллекта. Люди в списке ожидания пытаются заполучить продукт. Что это означает для развития креативной индустрии? О применении ИИ в..

    «Очень простой» эволюционный подход к обучению с подкреплением
    В прошлом семестре я посетил лекцию по обучению с подкреплением (RL) в моем университете. Честно говоря, я присоединился к нему официально, но я редко ходил на лекции, потому что в целом я нахожу..

    Освоение информационного поиска: создание интеллектуальных поисковых систем (глава 1)
    Глава 1. Поиск по ключевым словам: основы информационного поиска Справочная глава: «Оценка моделей поиска информации: подробное руководство по показателям производительности » Глава 1: «Поиск..

    Фишинг — Упаковано и зашифровано
    Будучи старшим ИТ-специалистом в небольшой фирме, я могу делать много разных вещей. Одна из этих вещей: специалист по кибербезопасности. Мне нравится это делать, потому что в настоящее время я..

    ВЫ РЕГРЕСС ЭТО?
    Чтобы понять, когда использовать регрессионный анализ, мы должны сначала понять, что именно он делает. Вот простой ответ, который появляется, когда вы используете Google: Регрессионный..

    Не зря же это называют интеллектом
    Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..

    LeetCode Проблема 41. Первый пропущенный положительный результат
    LeetCode Проблема 41. Первый пропущенный положительный результат Учитывая несортированный массив целых чисел, найдите наименьшее пропущенное положительное целое число. Пример 1: Input:..