Метод Flatten Ruby в C # - PullRequest
       23

Метод Flatten Ruby в C #

5 голосов
/ 13 октября 2008

Как я могу сделать метод Ruby Метод "Flatten" Ruby в C #. Этот метод выравнивает зубчатый массив в одномерный массив.

Например:

s = [ 1, 2, 3 ]           #=> [1, 2, 3]
t = [ 4, 5, 6, [7, 8] ]   #=> [4, 5, 6, [7, 8]]
a = [ s, t, 9, 10 ]       #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
a.flatten                 #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Ответы [ 3 ]

12 голосов
/ 13 октября 2008

Рекурсивное решение:

IEnumerable Flatten(IEnumerable array)
{
    foreach(var item in array)
    {
        if(item is IEnumerable)
        {
            foreach(var subitem in Flatten((IEnumerable)item))
            {
                yield return subitem;
            }
        }
        else
        {
            yield return item;
        }
    }
}

РЕДАКТИРОВАТЬ 1:

Джон объясняет в комментариях, почему это не может быть универсальным методом, посмотрите!

РЕДАКТИРОВАТЬ 2:

Мэтт предложил сделать это методом расширения. Вот, пожалуйста, просто замените первую строку на:

public static IEnumerable Flatten(this IEnumerable array)

и вы можете использовать его так:

foreach(var item in myArray.Flatten()) { ... }
2 голосов
/ 14 октября 2008

Я бы ответил в комментарии, но мне нужно более 300 символов.

@ Решение Александра великолепно, но оно сталкивается с проблемой с массивами строк. Поскольку string реализует IEnumerable, я думаю, что в конечном итоге он будет возвращать каждый символ в каждой строке. Вы можете использовать универсальный параметр, чтобы сказать ему, что вы надеетесь получить в этих случаях, например ::1003

public static IEnumerable Flatten<T>(IEnumerable e)
{
    if (e == null) yield break;
    foreach (var item in e)
    {
        if (item is T)
           yield return (T)item;
        else if (item is IEnumerable)
        {
            foreach (var subitem in Flatten<T>((IEnumerable)item))
                yield return subitem;
        }
        else
           yield return item;
    }
}
1 голос
/ 03 февраля 2010

Не могли бы вы просто использовать IEnumerable # SelectMany?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...