Удалить элементы в строке, разделенные запятыми в Groovy - PullRequest
0 голосов
/ 08 мая 2018

Я строю строку таким образом:

def presentationType = "${feedDisplayType}, ${moduleType}, ${cellType}"

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

Я хочу знать, есть ли какой-нибудь способ удалить это возможное нулевое значение в строке, или избегать добавления этого, когда они будут представлены.

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

Спасибо за любую помощь заранее.

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Есть 3 варианта:

1. GString интерполяция

def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()

2. Использование StringBuilder

def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
    sb.append(feedDisplayType)
    sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
    sb.append(moduleType)
    sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
    sb.append(cellType)
}
def presentationType = sb.toString()

3. Присоединение к списку с , в качестве разделителя

def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')

Benchmark

Прежде чем перейти к заключению, давайте протестируем все 3 метода, используя GBench tool:

@Grab(group='org.gperfutils', module='gbench', version='0.4.3-groovy-2.4')

def feedDisplayType = 'test'
def moduleType = null
def cellType = ''

def r = benchmark {

    'GString method' {
        def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
    }
    'StringBuilder method' {
        def sb = new StringBuilder()
        if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
            sb.append(feedDisplayType)
            sb.append(', ')
        }
        if (moduleType != null && !moduleType.isEmpty()) {
            sb.append(moduleType)
            sb.append(', ')
        }
        if (cellType != null && !cellType.isEmpty()) {
            sb.append(cellType)
        }
        def presentationType = sb.toString()
    }
    'Join list method' {
        def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
    }
}
r.prettyPrint()

выход

Environment
===========
* Groovy: 2.4.12
* JVM: OpenJDK 64-Bit Server VM (25.171-b10, Oracle Corporation)
    * JRE: 1.8.0_171
    * Total Memory: 236 MB
    * Maximum Memory: 3497 MB
* OS: Linux (4.16.5-200.fc27.x86_64, amd64)

Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On

                      user  system  cpu  real

GString method         265       2  267   268
StringBuilder method    72       4   76    77
Join list method       484       3  487   495

Заключение

Если вы стремитесь к максимальной пропускной способности, метод StringBuilder является лучшим (среднее время 77 наносекунд).

GString метод в несколько раз медленнее, чем StringBuilder, и он намного менее читабелен из-за всех операторов условия внутри одной строки GString. Это также довольно подвержено ошибкам - в этом случае легко допустить ошибку при интерполяции String.

Метод присоединения к списку является самым медленным (только в 2 раза медленнее, чем метод GString), но он является самым чистым. И это все еще довольно быстро - в большинстве случаев приемлемо 495 наносекунд. Конечно, оптимизация зависит от конкретного случая использования - если вам нужно выполнять эту часть кода миллион раз в секунду, тогда вместо этого использование StringBuilder имеет гораздо больший смысл.

Базовые угловые чехлы

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

Введите:

def feedDisplayType = 'lorem ipsum'
def moduleType = 'dolor sit amet'
def cellType = '123456789'

Выход:

                      user  system  cpu  real

GString method         387       1  388   390
StringBuilder method   170       0  170   175
Join list method       847       6  853   859

Введите:

def feedDisplayType = ''
def moduleType = ''
def cellType = ''

Выход:

                      user  system  cpu  real

GString method         237       5  242   242
StringBuilder method    44       0   44    44
Join list method       441       0  441   446
0 голосов
/ 08 мая 2018

Редактировать: Этот ответ был изменен, поскольку существует требование не печатать "," для нулевых терминов.

Рассмотрим:

def feedDisplayType = 'abc'
def moduleType = null
def cellType = 'ijk'

def f = { s, isLast = false ->
    def token = s ?: ''
    def seperator = (!s || isLast) ? '' : ',' 
    "${token}${seperator}"
}

def presentationType = "${f feedDisplayType}${f moduleType}${f cellType,true}"
assert 'abc,ijk' == presentationType

Обратите внимание, что при вызове функций в Groovy пароли необязательны, поэтому ${f x} эквивалентно ${f(x)}. f изначально был field в более ранней версии, но я сократил его для краткости.

...