Поиск пустых значений в несуществующем массиве:
*NL arrpos('probe659', 0) *NL arrpos('$probe659', '')
вернёт позицию 0, т. е. первую позицию массива, хотя, по-хорошему, хотелось бы получать -1, то есть "не найдено".
Неактивен
Неинициализированные переменные и ячейки массивов, числовые и текстовые, имеют значения по умолчанию '' и 0 соответственно.
Если 0 не найден в массиве, то он будет найден сразу за последним элементом массива(в нулевой позиции, если массив пуст), то бишь в первой же неинициализированной ячейке.
При этом стоит учесть то обстоятельство, что массивы неразрывны и "пробелов" между элементами нет: массив располагает свои элементы в ячейках от 0 до N - 1, где N - количество всех существующих элементов массива.
по-хорошему, хотелось бы получать -1, то есть "не найдено"
Оба поведения корректны в своем контексте. Вопрос же заключается в том, какое предпочтительнее для авторов.
Существующий вариант выгоднее тем авторам(A), для которых нет различий между "присвоенным"(инициализированным) значением 0 и "пустым"(неинициализированным), использующим массивы в заранее определенном диапазоне индексов.
Вариант с поиском исключительно инициализированных значений удобнее тем авторам(B), у которых "полезными" считаются значения инициализированные, а "бесполезными" - неинициализированные, при этом длина массива варьируется.
Минус первого варианта для авторов A и B - им придется делать проверку на выход за границы массива при поиске нулевых значений.
Минус второго варианта для авторов A - для работы с массивами им придется инициализировать их нулями. Это противоречит правилу QSP, перенятому из Бэйсика: неинициализированный массив считается заполненным нулями. Придется вводить явное различие между инициализированным значением и неинициализированным(сейчас оно тоже есть, но неявное). С другой стороны, в Бэйсике массивы заранее объявленной длины, поэтому там контекст немного другой.
Отредактировано Nex (06.09.2011 22:56)
Неактивен
Как раз в QSP-то, в отличие Бэйсика, размер массива и не задается!
Я писал об этом в предыдущем сообщении.
Массив считается теоретически бесконечным. Автор при использовании просто пользуется любыми ячейками массива на свое усмотрение.
Кстати, я был неправ насчет "пробелов" - они-таки инициализируются нулевыми значениями, начиная с нулевого индекса. Т.е. такой эксперимент:
probe[1]=20 probe[3]=30 ARRSIZE('probe')
выведет "4"!
Таким образом, весь интервал индексов, между последним инициализированным и нулевым(включительно), будет всегда заполнен как минимум "настоящими" нулями. Эта техника оказалась хитрее, чем я предполагал.
Но нулями он заполняется при присваивании. А как же удаление отдельных элементов через KILLVAR? Но KILLVAR тоже не оставляет пробелов! Как только из массива 1, 2, 3 мы удаляем 2, то получаем массив 1, 3 - два элемента на позициях 0 и 1 соответственно. "Хвост" массива сдвигается влево на 1, сохраняя массив неразрывным.
Раз целостность массивов сохраняется, то, пожалуй, стоит пересмотреть свои выводы.
Неактивен
Пересмотрел выводы, отредактировал первое сообщение. Оба варианта имеют свои недостатки.
Хорошим решением, теоретически, был бы ввод необязательного параметра, определяющего предполагаемый размер массива. Если указан - ищем значение в указанных пределах по первому способу, если не указан - в существующих элементах массива по второму. Беда в том, что авторам такие тонкости будет очень трудно объяснить.
Неактивен
Затем, что благодаря отсутствию явного задания длины массива, есть два способа их использования, я об этом писал выше.
Если автор использует массив самым простым способом - задав некую переменную(L), определяющую размер массива, то при заполнении произвольных ячеек внутри выбранного автором диапазона, размер полученного массива запросто может не совпасть с L. И вот тут-то, при поиске нулевых значений, в предложенном тобою варианте мы будем искать не по всей длине L, а лишь по отрезку заполненных элементов. Из-за этого придется явно инициализировать массив, о том, чем это плохо, я тоже писал. Перечитай.
Неактивен
Строковая индексация:
A["a"]="aaa" A["b"]="bbb" A["c"]="ccc"
Имеем:
A[0]="aaa", A["a"]="aaa"
A[1]="bbb", A["b"]="bbb"
A[2]="ccc", A["c"]="ccc"
Далее,
KILLVAR "A", 1
Имеем:
A[0]="aaa", A["a"]="aaa"
A[1]="ccc", A["c"]="ccc"
Т.о., числовые индексы поменялись, но это для нас неважно, т.к. мы пользуемся строковыми.
Что интересно, KILLVAR не поддерживает строковые индексы. Недоработка. Приходится явно указывать соответствующий числовой индекс.
Неактивен
Повторяю, есть два способа работы с массивами. Один из них опирается на "реальный размер массива", всегда известный через ARRSIZE, другой - на заданный автором диапазон.
Твое решение подходит только для тех, кто работает по первому способу.
На эту "недоработку" я давно уже пытался обратить внимание.
А кто помешал? Взял бы и обратил внимание, мое или Байта. На форумах ты об этом не писал.
Отредактировано Nex (08.09.2011 15:50)
Неактивен
См. тему "Как сделать?", последнюю страницу. Я там привел пример работы с двумерным массивом с размерностью, определенной автором(10x10).
Неактивен
Извиняюсь, я имел в виду тот же пример, но с адресацией через формулу m[row*row_width + column]. Невнимательно посмотрел.
Неактивен
Olegus t.Gl. написал:
Функция удаления элемента по строковому ключу здесь вообще не нужна
Не знаю, при чем здесь вообще удаление. Я про удаление не говорил.
Olegus t.Gl. написал:
Применительно же к функции ARRPOS ... в этой ситуации... куда полезнее по умолчанию ограничивать диапазон поиска функции ARRPOS реальным значением массива (ARRSIZE), но при этом добавить дополнительный параметр — верхнюю границу диапазона.
Как раз об этом я и говорил. Приятно видеть, что пытаясь меня переспорить ты пришел в итоге к тому же выводу.
Olegus t.Gl. написал:
Кстати, инициализация всех элементов данного массива производится одной строчкой
Как будто я этого не знал. Одной или десятью, сути это не меняет: явная инициализация массива противоречит принятой практике использования языка QSP.
Неактивен
Ну, ты понял наконец, о чем я говорил? Вот и славненько.
в своих объяснениях помимо "первого" и "второго" варианта различного использования массивов ты ещё вводишь понятия авторов "A" и "B", собирающихся использовать массивы каждый по-своему
Авторы "А" - используют один способ, авторы "B" - другой.
Отредактировано Nex (11.09.2011 19:50)
Неактивен