Передать свойство IO.DirectoryInfo в качестве параметра функции? (Часть вторая)

В другом вопросе (здесь: Передайте IO. Свойство DirectoryInfo в качестве параметра функции?) Я спросил о том, как улучшить функцию для передачи свойства DirectoryInfo в качестве параметра, проблема в том, что код работает только со свойствами "" верхнего уровня", такими как "Имя", " Root», «Диск» и т. д.

Но мне нужно было бы использовать такую ​​​​функцию:

Dim Folders As List(Of IO.DirectoryInfo) = blah bla blah...

For Each folderinfo In Bubble_Sort_List_DirectoryInfo(Folders, Function() New IO.DirectoryInfo("").Name)
    MsgBox(folderinfo.Name)
Next

Но мне нужно использовать такую ​​​​функцию еще:

For Each folderinfo In Bubble_Sort_List_DirectoryInfo(Folders, Function() New IO.DirectoryInfo("").Parent.Name.Length)
    MsgBox(folderinfo.Name)
Next

Что необходимо добавить/изменить в этой функции для управления использованием свойств DirectoryInfo, таких как "Name.Length" или "Parent.Name.Length" "?

Private Shared Function Bubble_Sort_List_DirectoryInfo(list As List(Of IO.DirectoryInfo), _
                                                     exp As Expression(Of Func(Of Object))) _
                                                     As List(Of IO.DirectoryInfo)

    Dim member As MemberExpression = _
        If(TypeOf exp.Body Is UnaryExpression, _
           DirectCast(DirectCast(exp.Body, UnaryExpression).Operand, MemberExpression), _
           DirectCast(exp.Body, MemberExpression))

    Return list.Select(Function(s) New With { _
    Key .OrgStr = s, _
    Key .SortStr = System.Text.RegularExpressions.Regex.Replace( _
                   s.Name, "(\d+)|(\D+)", _
                   Function(m) m.Value.PadLeft( _
                               list.Select(Function(folder) DirectCast(DirectCast(member.Member, PropertyInfo) _
                                                            .GetValue(folder, Nothing), Object).ToString.Length).Max(), _
                                                            If(Char.IsDigit(m.Value(0)), " "c, Char.MaxValue))) _
    }).OrderBy(Function(x) x.SortStr).Select(Function(x) x.OrgStr).ToList

End Function

ОБНОВИТЬ:

Это лишь некоторые пояснения и примеры.

Внутри каталога моего диска у меня есть несколько папок с такими именами папок:

80's
90's
2000-2006
2007
2008

В моем приложении я получаю папки с помощью метода "IO.Directory.GetDirectories" и сохраняю их в список DirectoryInfo().

Это входной список:

Dim Folders As List(Of IO.DirectoryInfo) = _
    IO.Directory.GetDirectories("E:\Música\Canciones", "*", IO.SearchOption.TopDirectoryOnly) _
    .Select(Function(p) New IO.DirectoryInfo(p)).ToList()

... Но метод «IO» заставляет содержимое списка сортироваться как строка, например:

2000-2006
2007
2008
80's
90's

Мой желаемый результат таков:

80's
90's
2000-2006
2007
2008

Итак, после создания списка с использованием метода «IO» мне нужно будет отсортировать содержимое списка, чтобы получить желаемый результат И ЭТО ИМЕННО ТО, ЧТО Я ПОЛУЧУ, ИСПОЛЬЗУЯ ФУНКЦИЮ ВЫШЕ, вызвав функцию, используя свойство «Имя». " в качестве параметра для пузырьковой сортировки папок по их свойству Name, поэтому я получаю желаемый результат.

проблема в том, что мне нужно использовать другие свойства, такие как "Name.Length" и "Parent.Name.Length", но функция позволяет использовать только свойство """TopLevel""", например "Name", "Parent" и т. д., но не переменные свойства.


person ElektroStudios    schedule 29.09.2013    source источник
comment
Я не видел первую часть этого, но почему бы не передать лямбда-выражение вместо строки? Таким образом, у вас будет некоторая функция (x) x.parent.name.length вместо Parent.Name.Length, а затем передать ее через addressof или, возможно, как переменную (из-за простоты).   -  person Neolisk    schedule 30.09.2013
comment
@Neolisk спасибо за комментарий, один человек показал мне решение с использованием лямбда, но у него та же проблема, я обновил свой вопрос со ссылкой на первую часть вопроса. Я предпочитаю использовать строки, потому что в этом случае путь к каталогу лямбда может быть пустым (например: function() new directoryinfo().Name ), но я хочу использовать эту функцию в общем виде, поэтому с другими типами объектов лямбда-выражение заставит меня создать экземпляр объекта, когда я просто не могу, надеюсь, вы меня понимаете, или, может быть, я ошибаюсь в IDK, касающемся использования лямбда, но в любом случае, используя строку или лямбда, я не могу решить эту проблему   -  person ElektroStudios    schedule 30.09.2013
comment
Вам не нужно создавать экземпляр объекта. Вы можете сделать лямбду на еще не существующем объекте. Думайте об этом как о чистой функции. Чистым функциям ничего не нужно для существования, они определяют рабочий процесс. Что-то входит, что-то уходит, ничего не сохраняется. Если вам нужен общий подход, вы можете сделать лямбда для типа Object. Никаких проверок во время выполнения, почти так же, как строки, но вы сохраняете приятный синтаксис лямбда.   -  person Neolisk    schedule 30.09.2013
comment
@Neolisk спасибо за объяснение, тогда я не могу использовать лямбды с каким-либо риском :).   -  person ElektroStudios    schedule 30.09.2013
comment
Я обновил код, используя лямбда-версию, пожалуйста, помогите мне!   -  person ElektroStudios    schedule 30.09.2013
comment
Забудьте о методологии, что вы пытаетесь сделать? Пожалуйста, предоставьте образец ввода и вывода. Ваш код выглядит слишком сложным.   -  person Neolisk    schedule 30.09.2013
comment
@Neolisk Я обновил вопрос, добавив информацию, спасибо за комментарий.   -  person ElektroStudios    schedule 30.09.2013
comment
Вы пробовали не сортировать их?   -  person Sebastien H.    schedule 30.09.2013
comment
Отлично, спасибо за обновление. Теперь можете ли вы объяснить словами, в чем смысл вашего способа сортировки. Я знаю, что это похоже на годы, но как именно в английских словах вы планировали разобраться с этим? Я спрашиваю, потому что длина не очень вам поможет, это приведет к следующему порядку: 80-е, 90-е, 2007, 2008, 2000-2006 (или аналогичный).   -  person Neolisk    schedule 30.09.2013
comment
Вы пытаетесь в основном сделать умную сортировку имен...   -  person It'sNotALie.    schedule 01.10.2013


Ответы (1)


Создайте класс, реализующий IComparer:

Public Class MyDirectoryInfoComparer
    Implements IComparer(Of IO.DirectoryInfo)

    Public Function Compare(x As IO.DirectoryInfo, y As IO.DirectoryInfo) As Integer _
        Implements IComparer(Of IO.DirectoryInfo).Compare

        ' x comes before y
        Return -1 ' or any number less than 0

        ' x is the same as y
        Return 0

        ' x comes after y
        Return 1 ' or any number greater than 0
End Function

Создайте свой список:

Dim Folders As List(Of IO.DirectoryInfo) = _
    IO.Directory.GetDirectories("E:\Música\Canciones", "*", IO.SearchOption.TopDirectoryOnly) _
    .Select(Function(p) New IO.DirectoryInfo(p)).ToList()

Затем используйте свой класс сравнения, чтобы отсортировать его:

Folders.Sort(New MyDirectoryInfoComparer)
person Riley McArdle    schedule 28.11.2013