Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Шарпей не тянет?  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
Такой вот вброс. Всю башню себе выломал.

Есть такая штука:

IEnumerable<IGrouping<'a>> something;


Расположены в правильном порядке.
Количество неизвестно.

Нужно составить дерево из этого добра, группируя по условиям, которые находятся в 'a

Пытаюсь заюзать aggregate, по концепции то, что надо.

То есть:

something.aggregate((result,next)=> result.GroupBy(x=> returnElementFromNext(x)))


Но GroupBy возвращает
IEnumerable<IGrouping<'a>>
, ну а по сигнатуре надо
IGrouping<'a>
.

Как быть?

Хочу сделать с LINQ, то есть без ручных обходов в императивном стиле.
Хочу сделать с анонимными классами (не хочу создавать класс для этой операции).


P.S. То есть -
IEnumerable<IGrouping<'a>> something;
- эта штука - перечисление элементов, которые лежат на одном уровне дерева. И их надо "просто" вложить в друг-друга.

Если чо - заготова.

                var arrayFirst = new[]
                {
                    new { bound = 1, value = "something on top" },
                    new { bound = 10, value = "on top too" },
                    new { bound = 30, value = "on top at end" }
                };

                var arraySlave = new[] {
                    new { bound = 2, value = "slaveOne" },
                    new { bound = 15, value = "second slave" },
                    new { bound = 37, value = "slave on end" }
                };

                var mainArray = new[] { arrayFirst, arraySlave }; //Вот этот парень.
1 июн 18, 18:10    [21462230]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
Агнец за бортом
Но GroupBy возвращает
IEnumerable<IGrouping<'a>>

, ну а по сигнатуре надо
IGrouping<'a>


Очень-очень странный запрос... Ну сделай First/Single, хотя и бред, но получишь свой IGrouping ))

Материализацию дерева из плоской коллекции без рекурсива, или yield, или стека, или промежуточного словаря -- не получить.


Агнец за бортом
Если чо - заготова.


Исходный лист давай.
1 июн 18, 20:18    [21462388]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2421
hVostt
Материализацию дерева из плоской коллекции без рекурсива, или yield, или стека, или промежуточного словаря -- не получить.

Ну почему? Если коллекция упорядочена и в элементах указывать индекс родителя, то ForEach и все.
1 июн 18, 21:15    [21462422]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
hVostt
Исходный лист давай


В исходном - дерево строк в экселе
1 июн 18, 21:37    [21462448]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
LR
Ну почему? Если коллекция упорядочена и в элементах указывать индекс родителя, то ForEach и все.


Упорядочена каким образом?
1 июн 18, 21:51    [21462465]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
Агнец за бортом
hVostt
Исходный лист давай


В исходном - дерево строк в экселе


Ну пример исходного массива, хотя бы из трёх элементов дай.
1 июн 18, 21:51    [21462467]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2421
hVostt
LR
Ну почему? Если коллекция упорядочена и в элементах указывать индекс родителя, то ForEach и все.


Упорядочена каким образом?

Таким, чтобы по указанному индексу находился родитель.
var arr = new[] { new { parentID = -1, name = "root", childs = new List<object>() },
    new { parentID = 0, name = "node-1", childs = new List<object>() },
    new { parentID = 0, name = "node-2", childs = new List<object>() },
    new { parentID = 1, name = "node-1-1", childs = new List<object>() },
    new { parentID = 1, name = "node-1-2", childs = new List<object>() },
    new { parentID = 2, name = "node-2-1", childs = new List<object>() } };
arr.Where(x => x.parentID >= 0).ToList().ForEach(x => arr[x.parentID].childs.Add(x));
1 июн 18, 22:52    [21462574]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
LR
Таким, чтобы по указанному индексу находился родитель.


Ну, короче, словарь. Да, я об этом и говорил.


hVostt
или промежуточного словаря
2 июн 18, 00:03    [21462651]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
LR
.ForEach(x => arr[x.parentID].childs.Add(x));


И опять таки, ForEach, это читерство, так как по сути это обычный цикл, а ТС хочет чистой функциональщины :)
2 июн 18, 00:05    [21462652]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2421
hVostt
Ну, короче, словарь. Да, я об этом и говорил.


hVostt
или промежуточного словаря

Тогда что есть "плоская коллекция" из которой надобно дерево "материализовывать"?

hVostt
И опять таки, ForEach, это читерство, так как по сути это обычный цикл, а ТС хочет чистой функциональщины :)

Так весь Linq - это обычные циклы:) А чего хочет ТС я так и не понял:)
2 июн 18, 00:32    [21462679]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
LR
чего хочет ТС я так и не понял


Чистая функция - знаешь, что это такое?
2 июн 18, 01:04    [21462693]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
LR
Тогда что есть "плоская коллекция" из которой надобно дерево "материализовывать"?


Коллекция объектов, у которых есть ID и Parent ID.

Вообще, на LINQ можна

    class Item
    {
        public int Id { get; set; }

        public int? ParentId { get; set; }

        public string Name { get; set; }
    }

    IEnumerable<Item> list = ...
 
    var tree = list
        .Aggregate(
            ((IEnumerable<(Item, Item[])>)(new(Item, Item[])[0]), list.ToLookup(p => p.ParentId)),
            (a, e) => (a.Item1.Concat(new[] { (e, a.Item2[e.Id].ToArray()) }), a.Item2))
        .Item1
        .Where(p => p.Item1.ParentId == null);


в tree будут корни...
2 июн 18, 02:34    [21462724]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 5303
hVostt
а ТС хочет чистой функциональщины :)

Тогда для чистоты эксперимента надо использовать F#.
2 июн 18, 03:50    [21462737]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 38643
Сон Веры Павловны
hVostt
а ТС хочет чистой функциональщины :)

Тогда для чистоты эксперимента надо использовать F#.
+1
ТС не перебарщивай с Linq.
Циклы это не зло).
2 июн 18, 08:55    [21462780]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 38643
Агнец за бортом
hVostt
Исходный лист давай


В исходном - дерево строк в экселе
хороший прыжок ...из экселя сразу в функциональный ЯП )).
2 июн 18, 08:57    [21462781]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
hVostt
LR
Тогда что есть "плоская коллекция" из которой надобно дерево "материализовывать"?


Коллекция объектов, у которых есть ID и Parent ID.

Вообще, на LINQ можна

    class Item
    {
        public int Id { get; set; }

        public int? ParentId { get; set; }

        public string Name { get; set; }
    }

    IEnumerable<Item> list = ...
 
    var tree = list
        .Aggregate(
            ((IEnumerable<(Item, Item[])>)(new(Item, Item[])[0]), list.ToLookup(p => p.ParentId)),
            (a, e) => (a.Item1.Concat(new[] { (e, a.Item2[e.Id].ToArray()) }), a.Item2))
        .Item1
        .Where(p => p.Item1.ParentId == null);



в tree будут корни...



Только "есть нюанс".

1. Класс с данными - анонимный.
2. Ссылки на родителя нет. (Не самая проблема)
2 июн 18, 09:42    [21462800]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2421
Агнец за бортом
LR
чего хочет ТС я так и не понял


Чистая функция - знаешь, что это такое?
Нет. Но попробую угадать: это нечто противоположное грязной функции, верно?

hVostt
Коллекция объектов, у которых есть ID и Parent ID.
Ну, короче, словарь :)
2 июн 18, 10:30    [21462838]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
Агнец за бортом
1. Класс с данными - анонимный.
2. Ссылки на родителя нет. (Не самая проблема)


Тогда только так:

// чтобы получать вложенные
var children =  anonymousList.ToLookup(p => p.ParentID);
// чтобы получать родителя
var parents = anonymousList.ToDictionary(p => p.ID);
// материализуем дерево
var tree = anonymousList
   .Select(item => new { 
      item, 
      parent = item.ParentID == null ? null : parents[item.ParentID.Value],
      children = children[item.ID]
    })
    .Where(p => p.item.ParentID == null)
    .ToList();
2 июн 18, 17:21    [21463195]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
hVostt,

А на JS, к слову - вообще без заморочек.
2 июн 18, 18:42    [21463237]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
Агнец за бортом
hVostt,

А на JS, к слову - вообще без заморочек.


Пример в студию.
2 июн 18, 20:27    [21463323]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 38643
hVostt
Пример в студию.

+1
В каждом ЯП свои подходы и границы "правильного" и "неправильного" в кавычках.
3 июн 18, 13:10    [21464112]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
Шарпей всё же "не тянет".


Агнец за бортом
Хочу сделать с анонимными классами (не хочу создавать класс для этой операции).


Вот это условие выполнить не удалось, в силу типизированной природы шарпа..

    
public class node 
    {

        public int row { get; set; }
        public String value { get; set; }     
        public node[] childs{get;set;}      
    }


Вот такой класс создать всё же пришлось.

Поскольку:
1. Уровни вложенности не ограниченны.
2. Через generic интерфейсы тип для Aggregate не задать (из-за п.1), а подчиненность выразить как-то надо.

Пришлось мутить такой вот класс.

Итоговый код - "две строчки".

Жаль, что не удалось на анонимных классах сделать.
4 июн 18, 11:03    [21465683]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
hVostt
Member

Откуда:
Сообщений: 16272
Агнец за бортом
Жаль, что не удалось на анонимных классах сделать.


На кортежах делается же.

Тебе какой больше по душе -- Tuple, ValueTuple?
4 июн 18, 11:14    [21465755]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
Пример кода.

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

namespace PIC_
{
    class nodeComparer : IEqualityComparer<node>
    {
        public bool Equals(node x, node y)
        {
            return x.row == y.row;
        }

        public int GetHashCode(node obj)
        {
            return obj.row.GetHashCode();
        }
    }
    public class node
    {

        public int row { get; set; }
        public String value { get; set; }
        public node[] childs { get; set; }
    }

    public static class treeBuilder
    {
        public static void build()
        {
            var arrayFirst = new[]
            {
                    new { row = 1, value = "something on top" },
                    new { row = 10, value = "on top too" },
                    new { row = 30, value = "on top at end" }
                };

            var arraySlave = new[] {
                    new { row = 2, value = "slaveOne" },
                    new { row = 15, value = "second slave" },
                    new { row = 37, value = "slave on end" }
                };

            var mainArray = new[] { arrayFirst, arraySlave }; //Вот этот парень.

            var finalTest = mainArray.Reverse().Select(x => x.Select(c => new node { row = c.row, value = c.value })
                            .OrderBy(c => c.row)
                            .AsEnumerable())
           .Aggregate((result, nextnode) => result.GroupBy(x => nextnode.Where(masterNode => masterNode.row < x.row)
                            .OrderByDescending(c => c.row).FirstOrDefault(), new nodeComparer())
                            .Select(x => new node { row = x.Key.row, value = x.Key.value, childs = x.ToArray() })
           );
        }
    }
}
4 июн 18, 11:20    [21465782]     Ответить | Цитировать Сообщить модератору
 Re: Шарпей не тянет?  [new]
Агнец за бортом
Member

Откуда:
Сообщений: 1318
hVostt
Тебе какой больше по душе -- Tuple, ValueTuple?


После того, как RAZOR не смог прожевать

Tuple<int,int,int>
- я не люблю ЭТО.
4 июн 18, 11:27    [21465807]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / WinForms, .Net Framework Ответить