2010-05-11 2 views
12

У меня есть строка, какЛучший способ закодировать это, строка для отображения преобразования в Groovy

def data = "session=234567893egshdjchasd&userId=12345673456&timeOut=1800000" 

Я хочу, чтобы преобразовать его в карту

["session", 234567893egshdjchasd] 
["userId", 12345673456] 
["timeout", 1800000] 

Это текущий путь я делаю it,

def map = [:] 

data.splitEachLine("&"){ 

    it.each{ x -> 

    def object = x.split("=") 
    map.put(object[0], object[1]) 

    } 

} 

Это работает, но есть ли более эффективный способ?

ответ

21

Я не знаю, думаю, что это будет работать быстрее, но это делает предложить себя с точки зрения синтаксической скупости:

def data = 'session=234567893egshdjchasd&userId=12345673456&timeOut=1800000' 
def result = data.split('&').inject([:]) { map, token -> 
    token.split('=').with { map[it[0]] = it[1] } 
    map 
} 

Лично мне ответ Дона для читаемости и ремонтопригодность, но в зависимости от контекста, это может быть целесообразным.

Редактировать: Это фактически переформатированный однострочный.

+3

+1 для использования причудливых методов GDK (инжекция) и причудливых английских фраз (синтаксическая оценка) –

+2

вы можете изменить инъекцию intrace.split ('='). с {map << [(it [0]): it [1]]} если вы _really_ ненавижу читаемость ;-) –

+0

Мне понравилось это решение - пока я не обнаружил, что есть функцию "collectEntries()", которая может использоваться для построения карт. Это более читаемо, чем «inject()», см. Мой ответ ниже. –

11

Я не знаю, если это более эффективно, но на моих глазах, это немного проще (YMMV)

def data = "session=234567893egshdjchasd&userId=12345673456&timeOut=1800000" 
def map = [:] 

data.split("&").each {param -> 
    def nameAndValue = param.split("=") 
    map[nameAndValue[0]] = nameAndValue[1] 
} 
+2

Я написал быстрый и грязный сценарий Groovy (возможно, довольно ошибочный), сравнивая упомянутые 3 техники и последовательно применяя метод Dons. Он захватил 3 строки запроса различной длины и был рассчитан как долго для каждого метода, например: 'Метод 1 (ig0774) [124727794, 2236178, 4806756] всего: 131770728 Метод 2 (Дон) [2546134, 1174801, 2227867] всего: 5948802 Метод 3 (Ted Naleid) [10447068, 1915955, 2840445] всего: 15203468 «Хорошо для моих целей» – Steve

5

Если вы ищете эффективные регулярные выражения, где это в:

def data = "session=234567893egshdjchasd&userId=12345673456&timeOut=1800000" 
def map = [:] 
data.findAll(/([^&=]+)=([^&]+)/) { full, name, value -> map[name] = value } 

println map 

принтами:

[session:234567893egshdjchasd, userId:12345673456, timeOut:1800000] 

Если вы не знакомы с регулярными выражениями, это может выглядеть немного чужой, но это действительно не так сложно. У него просто две (группы), первая группа - любой символ, но «&» или «=». Вторая группа - любой символ, кроме «=». Группы захвата расположены по обе стороны от «=».

1

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

def map = data.split('&').collectEntries { 
     def kvp = it.split('=').collect { string -> 
      string = string.trim() 
      return string 
    } 
    [(kvp[0]): kvp.size() > 1 ? kvp[1] ?: '' : ''] 
    // the null check is almost certainly overkill so you could use :- 
    // [(kvp[0]): kvp.size() > 1 ? kvp[1] : ''] 
    // this just checks that a value was found and inserts an empty string instead of null 
} 
1

После некоторых поисков, «collectEntries() "- это волшебная вещь для использования, она создает элемент карты. Работайте так же, как «collect()», который создает список.Поэтому, учитывая

def params = "a1=b1&a2=b2&a3&a4=&a5=x=y" 

один-лайнер

map = params.tokenize("&").collectEntries{ 
      it.split("=",2).with{ 
       [ (it[0]): (it.size()<2) ? null : it[1] ?: null ] 
      } 
     } 

, который создает

map = [a1:b1, a2:b2, a3:null, a4:null, a5:x=y] 

В зависимости, как вы хотите обрабатывать случаи "a3" и "a4 =" Вы можете также использовать немного более короткая версия

... 
[ (it[0]): (it.size()<2) ? null : it[1] ] 
... 

, а затем вы получите это:

map = [a1:b1, a2:b2, a3:null, a4:, a5:x=y] 
Смежные вопросы