Перейти к контенту

Рекомендуемые сообщения

@Nazgool, Т.к. речь начиналась с необходимости создания именно "дубликата", то @Kirgudu более прав (или "правее"?) чем Вы.

ipairs "продублирует" массив только до первого появления nil в качестве значения элемента массива. Ведь именно поэтому второй вариант  вашего примера ничего на печать и не выводит (хотя массив и не пустой),  а массивы со значением nil -  не такая уж и редкая вещь. Естественно я рассматриваю только массивы c числовыми индексами (ключами), которые и приведены в Вашем примере. Использование pairs "дубль" не создаст, хоть вы и получите новый массив без элементов со значениями nil.  ИМХО.

Изменено пользователем Serge!
Ссылка на комментарий

@Serge!

 

она просто рассчитана на неассоциированный массив без вложений

Т.е. копируем массив всё-таки.
И если до копирования работать с массивом правильно, посредством функции table.remove и др., то у Вас в массиве никогда не будет полей со значением nil.
Поэтому и копирование с помощью irairs создаст точную копию такого массива.

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

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

Изменено пользователем Nazgool
Ссылка на комментарий

@Nazgool, @Serge!,

Ситуация с nil в качестве элементов массивов - это ситуация нестандартная, вызывающая неопределённое поведение. Следует вообще исключить её из практики. Поэтому обсуждение, как продублировать подобный массив с nil-ами - следует перевести в плоскость "как убрать необходимость его дублировать и вообще убрать такой массив".

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

@Nazgool, я ж не особо и спорю, и полностью согласен с тем, что все зависит от того, чем и как именно массив заполнен.

Но если я знаю, что массив всегда заполняется правильно, и - опять же если, - кол-во значений в нём может вырасти до больших величин или обработка самого массива находится внутри большого цикла (оставим в стороне оптимальность самих таких конструкций) - применение оператора "#" становится существенно более выгодным с точки зрения производительности.

Всё зависит от целей и методов/качества реализации. Я тоже предпочитаю использовать ipairs, но бывают случаи, когда лучше отступить от канонов. Потому и упомянул. :)

Собственно, только автор вопроса может окончательно решить, что ему больше подходит.

Ссылка на комментарий

@Malandrinus,

Абсолютно согласен с тем, что массивы с nil-ами это зло.

А необходимость копирования таблиц (с nil-ами или без них) можно определить только после того, как будут известны общие цели и задачи скрипта.
Но в это мы не посвящены, поэтому принимаем задачу как есть - т.е. нужно копировать.
И насчет того, чтобы "вообще убрать такой массив" я уже неоднократно говорил.
Если работать с массивами правильно, то такой необходимости не возникнет в принципе.
 
Хоть в сталкере используется lua 5.1.4, но компилируется код с помощью luajit 1.1.5 (или ошибаюсь?)
И если у тебя есть возможность протестировать оба варианта (for i=1,#t и ipairs) в  luajit, то заметной разницы в скорости выполнения ты не увидишь.
Изменено пользователем Nazgool
Ссылка на комментарий
Если работать с массивами правильно, то такой необходимости не возникнет в принципе.

Я бы так категорично и однозначно говорить поостерёгся. Например, таблица с дефолтными параметрами, некоторые из которых в ней должны присутствовать, но определяются позже в процессе инициализации. Вполне реальная ситуация.

 

 

 

оба варианта (for i=1,#t и ipairs) в  luajit, то заметной разницы в скорости выполнения ты не увидишь.

Говорить о скорости при обработке таблиц в цикле for для Lua (в разрезе Сталкера с его относительно небольшими таблицами) это просто разговор ради чтоб поговорить. Lua разрабатывался для обработки именно таблиц с миллионами элементов. А цикл for там (по заверению разработчиков) один из самых оптимальных и быстрых.

Изменено пользователем Serge!
Ссылка на комментарий

@Serge!

Ну обсуждалось же уже. Ладно.

Вот случай, описанный тобой.
Есть массив, похожий на тот, что ты упоминал :
local t = {nil,2}
1-я проблема. Определять поля нужно сразу
local t = {}
t[1]=nil
t[2]=2
Так уже не работает!
 
В этом массиве опрелено только одно поле по индексу [2].
В процессе (например) нужно сначала добавить поле с индексом [3]
 
2-я проблема. local t = {nil,2,nil} - третий nil как ты говоришь "должен присутствовать", но валит весь массив.
И ты не сможешь его перебирать, т.е. и уже определенное значение в поле [2] пропадает.
 
Поэтому нужно оставлять в таком виде для целостности массива
local t = {nil,2}
и теперь нужно добавиить поле [3], как у тебя "позже в процессе инициализации"

t[3]='a'
3-я проблема. Массив валиться с этим добавлением.
 
Пока хватит. И так проблема на проблеме. Кому это нужно?

 

 

 

И да. При использовании функций-итераторов выполняются некоторые дополнительные инструкции, но в контексте luajit время их выполнения минимизируется по сравнению с (как уже выяснилось) не 100%-но надежным оператором #.

Но в контексте надежности кода, использование стандартных методов намного предпочтительнее, чем гонка за сомнительной прибавкой в скорости. Тем более, как ты сам сказал, при работе с небольшими таблицами сталкера.

Изменено пользователем HellRatz
Ссылка на комментарий

 

 

таблица с дефолтными параметрами, некоторые из которых в ней должны присутствовать, но определяются позже в процессе инициализации

Понимаешь, в соответствии со стандартом языка невозможно сделать такие параметры со значениями nil. Если так поступаешь, то нарушаешь стандарт и нарываешься на неопределённое поведение. Неопределённое не значит, что совершенно невозможно сказать, что произойдёт. Например для случая этих массивов с "дырками в виде nil" поведение вполне известно для реализации Lua в ванильном сталкире. Но эти же массивы с дырками ведут себя совершенно иначе в реализации LuaJIT 2х. Там уже невозможно делать трюки, которые можно было делать в LuaJIT 1х и в частности работа с такими массивами в LuaJIT 2х практически полностью приведена в соответствие со стандартом, что означает невозможность определить его длину никаким способом.

 

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

 

Короче, просто категорически нельзя рассчитывать на некое нестандартное поведение. То, что разрабы пыс так поступали, говорит только об уровне скриптёров, которых они тогда набирали. Это никак не может быть ориентиром для всех остальных.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий
в соответствии со стандартом языка невозможно сделать такие параметры со значениями nil.

Позвольте с Вами не согласиться. А как-же целое понятие о "слабых таблицах" введённых и подробно рассмотренных разработчиками языка? Я не проверял работает ли это в Lua Сталкера, но и пока нигде не читал, что это не применимо.

К тому же вспомните про параметры функции. Это что? Таблица - передается через стек, но стек в Lua это тоже таблица. А помните, что пареметры позиционно зависимы и могут отсутствовать, но их позиция должна быть определена? А это что такое? Дырки - т.е. nil. Вам никогда не встречались дистрибутивные функции, в которых прописана проверка параметров на nil? Мне встречались. Далее: "Последние отсутствующие параметры могут просто не указываться". Вам такое ничего не напоминает? Но ведь это стандарт языка в части определения таблиц. Так возможны и применимы или нет - nil в таблицах? А Вы говорите... см. цитату.

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

Работать можно заставить почти всё... даже стандартные методы, но не совсем стандартными способами и подходами. Практика говорит именно о таком.

 

P.S. Дискуссия по этому вопросу (не слишком существенному) и впрям затянулать. Боюсь получить очередное взыскание, а по сему это было последнее, что я говорю по этому поводу. Все остальные непонятки только в ЛС, если у кого такое желание возникнет (прошу заранее снисхождения, т.к. я их читаю очень не регулярно).

P.P.S. Что касается LuaJIT 2х, то про это в разрезе Сталкера говорить вообще не стоит, т.к. если это и будет кем-то реализовано???, то это уже будет не этот Сталкер и не этот форум.

Изменено пользователем Serge!
Ссылка на комментарий

вспомните про параметры функции

Вот. Замечательный пример. Поскольку для доступа к аргументам надо знать их количество, то есть специальная функция select(index, ...) для определения количества аргументов и доступа к нужному аргументу по индексу. Функция специально добавлена для того, чтобы не нарушать стандарт языка и не прибегать ко всяким небезопасным трюкам.

 

Это что? Таблица - передается через стек, но стек в Lua это тоже таблица.

 

Стек - это стек, таблица - это таблица. Это разные вещи. Список аргументов можно сконвертировать в таблицу, но тогда вылазят соответственно все ограничения стандарта на таблицы, включая невозможность надёжно узнать их количество, если реализация языка строго следует стандарту. И как раз для этого есть функция select.

 

понятие о "слабых таблицах"

 

Это вообще не о том.

 

Что касается LuaJIT 2х, то про это в разрезе Сталкера говорить вообще не стоит, т.к. если это и будет кем-то реализовано???, то это уже будет не этот Сталкер и не этот форум.

 

=) Вот бы этот пуризм да в мирное русло, например применительно к вычищению всякой грязной нестандартщины из вашего любимого "того Сталкира". Но нет, вся энергия направляется на защиту заведомо ошибочного подхода.

 

 

Если работать с массивами правильно, то такой необходимости не возникнет в принципе.

Ну так и я о том же. Разумеется, я не имел в виду "убрать все массивы вообще" =) Какой-то массив останется, просто он не должен быть неправильно сформирован. Ничто не мешает, например, заменить значения nil ну скажем строками "nil" и проверять эти значения, трактуя их как "пустой аргумент". Всё, проблемы нет. Кстати, именно так кое-где в движке и поступают.

Изменено пользователем Malandrinus
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий
Ну если массив, то почему не ipairs ? 

Так "pairs" так же можно использовать и для неассоциированных массивов, в чём проблема?

Много сказано про "дырки" в массивах, это про то, когда обнуляется путём "tbl[1] = nil"? Если да, то где могут понадобиться эти самые "дырки"? :huh:

Изменено пользователем FonSwong
Ссылка на комментарий

Не хотел продолжать, но Вам отказать не могу. Уважаю.

 

Стек - это стек, таблица - это таблица. Это разные вещи.

А как быть с этим? Только цитаты из "Программирование на языке Lua. Третье издание."

1. "Таблицы являются главным (на самом деле единственным) механизмом структурирования данных в Lua."

2. "Поскольку таблицы являются динамическими сущностями, то реализовать связанные списки в Lua довольно легко."

3. "... Например, мы можем представить стек как (неограниченный) массив.".

А теперь спросим: Что такое же это такое стек? Я (и не только я) отвечу - это связанный список.

А что такое связанный список (т.е. стек) в понятиях и реализации Lua? Ваш ответ.

 

Это вообще не о том.

Не скажите. Весь этот механизм и был для этого разработан, т.к. таблицы МОГУТ иметь и ключи и значения nil, т.е. для нас здесь существенно что могут! и имеют (они им не свойственны и, в некоторых случая, противопоказаны, но могут же!). Вот ведь даже Разработчики так предполагали и разработали механизм для купирования таких моментов. Для чего? Это другой вопрос и мы сейчас не об этом. Правильно это или не правильно... сейчас тоже не об этом. А об этом сейчас что? - то, что такое возможно.

 

просто он не должен быть неправильно сформирован.

А вот это чистый популизм. Массив должен быть сформирован так, как это требуется для решения поставленной задачи. Всё остальное зависит от квалификации исполнителя в определённой области знаний. Посмотрите вокруг. Сколько ваших коллег для решения своих (не самых трудных) задач правят движок сталкера, хотя они подчас могут быть решены и без такого грубого вмешательства? Я противник этого и поэтому для решения своих проблем ищу лазейки в рамках определённых мне разработчиками. А кто ищет, тот почти всегда находит.

 

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

Что значит "нестандарщины" из вашего любимого "того Сталкира"? У Вас есть другой Сталкер? Где я могу посмотреть стандарт, от которого так отличается "тот Сталкер"? Фи, это не солидно. Сколько лет уже живёт этот "ошибочный подход"? А сколько лет живут или жили те творения, которые сделаны на его основе? Статистики пока нет, это точно. Да, "тот Сталкер" (ЧН практически не знаю) мне симпатичен. Это плохо? Новые? Симпатичны далеко не все. Это хорошо?

А зашищать?... это очень далеко от меня. Я просто иногда занимаюсь тем, что мне интересно на данный момент.

 

Теперь точно всё.

Изменено пользователем Serge!
Ссылка на комментарий

 

 

Например, мы можем представить стек как (неограниченный) массив.".

В этом документе речь идёт о стеке в общем смысле, как одной из структур данных. Стек Lua к этому отношения не имеет.

 

 

 

Весь этот механизм и был для этого разработан, т.к. таблицы МОГУТ иметь и ключи и значения nil

Не могут. Ключом nil не может быть вообще, а значением может стать только в обход стандарта. Ещё раз повторяю, weak reference - это вообще не о том.

 

 

 

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

Но в рамках заданных правил языка. В противном случае имеем неприятности. Если программист этих неприятностей в упор не видит, то

 

 

 

зависит от квалификации

 

этой самой квалификации у него попросту не хватает.

 

 

 

Что значит "нестандарщины" из вашего любимого "того Сталкира"?

То и означает. Например выжигание калёным железом всех случаев применения обсуждаемого нестандартного поведения. Жечь напалмом, а не обсуждать, как с этим жить.

 

 

 

Сколько лет уже живёт этот "ошибочный подход"?

Пора уже избавляться от синдрома утёнка. Особенно в отношении заведомо кривых вещей.


 

 

где могут понадобиться эти самые "дырки"?

 

Допустим, передаём куда-то массив с аргументами и аргументы надо парсить в определённом порядке, и какие-то из них могут отсутствовать. Причём в ходе парсинга отсутствующие элементы тоже на самом деле парсятся, просто вместо значений подставляются некие значения по умолчанию. Соответственно, надо знать сколько этих аргументов, включая возможное количество "дырок" как в середмне, так и в конце. Надо также их перебрать все, включая и "дырки" (и те, что в конце, тоже).

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий
в чём проблема?

Вот в чем.

Если почитать описание функции pairs, она использует как итератор функцию next.

А для функции next записано :

Порядок следования индексов неопределен, даже для числовых индексов. (Для прохождения по таблице в числовом порядке, используйте числовой for или функцию ipairs.) 

Т.е. разрабы и сами не уверены, что pairs верно распарсит правильный массив.

Да и когда кто-то будет читать твой код, то увидев ipairs сразу поймет что парсится массив, а не всё подряд.

 

Изменено пользователем Nazgool
Ссылка на комментарий

т.к. таблицы МОГУТ иметь и ключи и значения nil, т.е. для нас здесь существенно что могут! и имеют (они им не свойственны и, в некоторых случая, противопоказаны, но могут же!). Вот ведь даже Разработчики так предполагали и разработали механизм для купирования таких моментов. Для чего? Это другой вопрос и мы сейчас не об этом. Правильно это или не правильно... сейчас тоже не об этом. А об этом сейчас что? - то, что такое возможно.

Таблицы не могут иметь ни ключей, ни значений nil

2.1

The type table implements associative arrays, that is, arrays that can be indexed not only with numbers, but with any Lua value except nil and NaN. (Not a Number is a special value used to represent undefined or unrepresentable numerical results, such as 0/0.) Tables can be heterogeneous; that is, they can contain values of all types (except nil). Any key with value nil is not considered part of the table. Conversely, any key that is not part of a table has an associated value nil.

Т.е. разрабы и сами не уверены, что pairs верно распарсит правильный массив.

pairs обойдет всю таблицу, в этом разрабы не просто уверены, они гарантируют это. А порядок при копировании, например, и не важен. Изменено пользователем abramcumner
Ссылка на комментарий

@abramcumner

Изначально речь шла о копировании массива. Правильно индексированного, без "дырок" списка.

В функции использовался pairs.

Как можно копировать такой массив с помощью pairs если:

Порядок следования индексов неопределен, даже для числовых индексов !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

И

разрабы и сами не уверены, что pairs верно распарсит правильный массив.

Я ни слова не сказал о том, что он не обойдет всю таблицу. Обойдет, конечно же обойдет. Но как?

Обойдет как написано в первой цитате. Т.е. а кто его знает как.

И что же мы скопируем?

 

Поэтому - ipairs

Кому не нравиться - тому _G.ipairs

А кому и это не нравиться, тогда local kak_ni_kruti_vse_ravno_ipairs = ipairs

Изменено пользователем Nazgool
  • Согласен 1
Ссылка на комментарий

 

 

когда порядок не важен то и не важно чем пользоваться

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

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Насколько я помню, обнаружение ГГ другими существами происходит в определенном радиусе от ГГ.

Сам вопрос: возможно ли обнаружение ГГ, либо одного из НПС другими НПС сделать зависимым не от дистанции, а допустим от направления "взгляда" НПС или другого параметра. Цель: стелс-режим по возможности аналогии с "Хитмэном".

Ссылка на комментарий

@Серый Волк, Есть такой мод, загугли. Так и называется стелс мод. А так тебе нужно менять параметр eye_fov по пути gamedata\config\creatures\ (а тут твое существо, нпс или монстр).

  • Спасибо 1
Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...