Groovy / Java-метод для преобразования вложенного представления List String обратно в List - PullRequest
3 голосов
/ 26 августа 2010

Мне нужно преобразовать строковое представление вложенного списка обратно во вложенный список (строк) в Groovy / Java, например,

String myString = "[[one, two], [three, four]]"
List myList = isThereAnyMethodForThis(myString)

Я знаю, что есть метод Groovy .split для разделения строкнапример, через запятую, и что я мог бы использовать регулярные выражения для идентификации вложенных списков между [и], но я просто хочу знать, существует ли существующий метод, который может это сделать, или я должен сам написать этот код.

Полагаю, самым простым было бы конструктор List, который принимает представление String в качестве аргумента, но я не нашел ничего подобного.

Ответы [ 2 ]

7 голосов
/ 26 августа 2010

В Groovy, если ваши строки разделены как таковые, вы можете сделать это:

String myString = "[['one', 'two'], ['three', 'four']]"
List myList = Eval.me(myString)

Однако, если они не разделены, как в вашем примере, я думаю, вам нужно начать играть с оболочкой и пользовательским связыванием ...

class StringToList extends Binding {
  def getVariable( String name ) {
    name
  }
  def toList( String list ) {
    new GroovyShell( this ).evaluate( list )
  }
}

String myString = "[[one, two], [three, four]]"
List myList = new StringToList().toList( myString )

Изменить, чтобы объяснить вещи

Binding в Groovy "Представляет привязки переменных скрипта, которые можно изменить извне объекта скрипта или создать вне скрипта и передать в него."

Итак, здесь мы создаем пользовательскую привязку, которая возвращает имя переменной при запросе переменной (под этим подразумевается установка значения по умолчанию для любой переменной для имени этой переменной).

Мы устанавливаем это как привязку, которую GroovyShell будет использовать для оценки переменных, а затем запускаем строку, представляющую наш список, через оболочку.

Каждый раз, когда оболочка встречает one, two и т. Д., Она предполагает, что это имя переменной, и начинает искать значение этой переменной в привязке. Привязка просто возвращает имя переменной и помещается в наш список

Другое редактирование ... Я нашел более короткий путь

Вы можете использовать Карты как связывающие объекты в Groovy, и вы можете использовать закрытие withDefault для Карт, чтобы при отсутствии ключа результат этого закрытия возвращался как значение по умолчанию для этого ключа. Пример можно найти здесь

Это означает, что мы можем сократить код до:

String myString = "[[one, two], [three, four]]"
Map bindingMap = [:].withDefault { it }
List myList = new GroovyShell( bindingMap as Binding ).evaluate( myString )

Как видите, Карта (благодаря withDefault) возвращает ключ, который был ей передан, если он отсутствует на Карте.

2 голосов
/ 26 августа 2010

Я бы разобрал эту строку вручную. Каждый раз, когда вы видите, что '[' создает новый Список, каждый раз, когда вы видите ',' добавляете элемент в список, и каждый раз, когда вы видите, что ']' возвращается.

рекурсивным методом.

public int parseListString(String listString, int currentOffset, List list){
    while(currentOffset < listString.length()){
        if(listString.startsWith("[", currentOffset)){
            //If there is a [ we need a new List
            List newList = new ArrayList();
            currentOffset  = parseListString(listString, currentOffset+1, newList);
            list.add(newList);
        }else if(listString.startsWith("]", currentOffset){
            //If it's a ], then the list is ended
            return currentOffset+1;
        }else{
            //Here we have a string, parse it until next ',' or ']'
            int nextOffset = Math.min(listString.indexOf(',', currentOffset), listString.indexOf(']', currentOffset));
            String theString = listString.substring(int currentOffset, int nextOffset);
            list.add(theString);

            //increment currentOffset
            currentOffset = nextOffset;
        }
    }
    return currentOffset;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...