Как сравнить одно значение в таблице со списком других значений в другой таблице

#lua #lua-table

#lua #lua-таблица

Вопрос:

У меня есть две таблицы:

 a = {customer1:1234, customer2:3456, customer3:4567, customer4:3456}
b = {2345, 1234, 3456, 6789}
  

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

Пожалуйста, можете ли вы посоветовать, как я могу этого добиться?

Ответ №1:

Вы можете сравнить обе таблицы поэлементно, используя циклы.

Пожалуйста, прочитайте ссылку на Lua.

http://www.lua.org/manual/5.3/manual.html#3.3.4
http://www.lua.org/manual/5.3/manual.html#3.3.5

простой пример

 local a = {1, 2, 3}

for k, v in pairs(a) do

  print(v)
end
  

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

Пожалуйста, обратите внимание, что

 a = {customer1:1234}
  

вызовет ошибку скрипта. Заменить : на =

Комментарии:

1. Предлагаемое вами решение приведет к #a итерациям b и #b итерациям a, хотя

2. Я знаю. Как я уже сказал, это простой пример. Если я дам ему полное оптимизированное решение, он просто скопирует и ничего не узнает.

3. Спасибо @Пятачок, … Воспользуюсь вашим советом здесь и посмотрю, смогу ли я решить свой вопрос.

Ответ №2:

Предполагая, что вы хотите удалить значения из обеих таблиц, я бы выбрал следующий подход:

  1. Повторите a и добавьте его значения в набор s_a
  2. Итерация b . Если значение есть s_a , добавьте его в набор s_b , если нет, удалите его b .
  3. (необязательно) s_a = nil; collectgarbage() для освобождения некоторой памяти
  4. Повторите a и удалите значения, которые вы не нашли в s_b

Моя реализация:

 local s_a, s_b, iter_b = {}, {}, ipairs(b)
--starting with b because ipairs is a bit cheaper than pairs if done right
for k,v in iter_b do
  s_b[v]=true;
end
for k,v in pairs(a) do
  if s_b[v] then
    s_a[v]=true
  else
    a[k]=nil
  end
end
s_b = nil; collectgarbage()
for k,v in iter_b do
  if not s_a[v] then b[k] = nil
end
  

Комментарии:

1. что вы имеете в виду, когда ipairs немного дешевле, чем pairs?

2. Это была своего рода ошибка, но не совсем. Я просто вспомнил это немного неправильно; Поскольку ipairs возвращает итератор без состояния, его можно использовать более чем в одном цикле, экономя затраты на создание нового замыкания, но в данном случае это не применимо, если вы не сделаете что-то вроде local iter = ipairs(b) . Я отредактирую это через мгновение.