Diferencia entre revisiones de «Módulo:Tablas»

De Hispanopedia
imported>Juan Mayordomo
Sin resumen de edición
Supremo (discusión | contribs.)
m 1 revisión importada
 
(No se muestran 25 ediciones intermedias de 7 usuarios)
Línea 1: Línea 1:
local z = {}
local z = {}
-- Código copiado de http://lua-users.org/wiki/SortedIteration
function __genOrderedIndex( t )
    local orderedIndex = {}
    for key in pairs(t) do
        table.insert( orderedIndex, key )
    end
    table.sort( orderedIndex )
    return orderedIndex
end
function orderedNext(t, state)
    -- Equivalent of the next function, but returns the keys in the alphabetic
    -- order. We use a temporary ordered key table that is stored in the
    -- table being iterated.
    local key = nil
    --print("orderedNext: state = "..tostring(state) )
    if state == nil then
        -- the first time, generate the index
        t.__orderedIndex = __genOrderedIndex( t )
        key = t.__orderedIndex[1]
    else
        -- fetch the next value
        for i = 1,table.getn(t.__orderedIndex) do
            if t.__orderedIndex[i] == state then
                key = t.__orderedIndex[i+1]
            end
        end
    end
    if key then
        return key, t[key]
    end
    -- no more value to return, cleanup
    t.__orderedIndex = nil
    return
end
function orderedPairs(t)
    -- Equivalent of the pairs() function on tables. Allows to iterate
    -- in order
    return orderedNext, t, nil
end
function z.tostringordered(tabla, identacion)
    identacion = identacion or '\n'
    local identacion2 = identacion .. '  '
   
    if not tabla then
    return
    end
   
    local valores = {}
    local k2, v2
    for k,v in orderedPairs(tabla) do
    if type(k) == 'string' then
    k2 = '"' .. k .. '"'
    else
    k2 = k
    end
        if type(v) == 'table' then
            v2 = z.tostringordered(v, identacion2)
        elseif type(v)=='string' then
        v2 = '"' .. v .. '"'
        else
        v2 = tostring(v)
        end
       
        table.insert(valores, '[' .. k2 .. '] = ' .. v2)
    end
    return '{' .. identacion2 .. (table.concat(valores, ', ' .. identacion2) or '') .. identacion .. '}'
end


function z.tostring(tabla, identacion)
function z.tostring(tabla, identacion)
     identacion = identacion or '\n'
     identacion = identacion or '\n'
     local resultado = ''
     local identacion2 = identacion .. ' '
      
      
     if not tabla then
     if not tabla then
     return
     return
     end
     end
   
    local valores = {}
    local k2, v2
   
   
     for k,v in pairs(tabla) do
     for k,v in pairs(tabla) do
     if type(k) == 'string' then
     if type(k) == 'string' then
     k2='"' .. k .. '"'
     k2 = '"' .. k .. '"'
     else
     else
     k2=k
     k2 = k
     end
     end
         if type(v)=='table' then
         if type(v) == 'table' then
             resultado = resultado .. identacion .. k2 .. ': {' .. z.tostring(v,identacion .. '  ') .. identacion .. '}'
             v2 = z.tostring(v, identacion2)
         elseif type(v)=='string' then
         elseif type(v)=='string' then
         resultado = resultado .. identacion .. k2 .. ': "' .. v .. '"'
         v2 = '"' .. v .. '"'
         else
         else
         resultado = resultado .. identacion .. k2 .. ': ' .. tostring(v)
         v2 = tostring(v)
         end
         end
       
        table.insert(valores, '[' .. k2 .. '] = ' .. v2)
     end
     end
   
   
     return resultado
     return '{' .. identacion2 .. (table.concat(valores, ', ' .. identacion2) or '') .. identacion .. '}'
end
 
function z.elemento(tabla, indice1, indice2, indice3, indice4, indice5, indice6, indice7)
local resultado
if not tabla or not indice1 then
return
end
resultado = tabla[indice1]
if not indice2 or not resultado then
return resultado
end
resultado = resultado[indice2]
 
if not indice3 or not resultado then
return resultado
end
resultado = resultado[indice3]
if not indice4 or not resultado then
return resultado
end
resultado = resultado[indice4]
if not indice5 or not resultado then
return resultado
end
resultado = resultado[indice5]
if not indice6 or not resultado then
return resultado
end
resultado = resultado[indice6]
if not indice7 or not resultado then
return resultado
end
resultado = resultado[indice7]
return resultado
end
end


Línea 48: Línea 177:
      
      
     return copia
     return copia
end
function z.insertar(tabla, elemento)
if not elemento then
return false
end
if not z.en(tabla, elemento) then
table.insert(tabla, elemento)
end
return true
end
end


Línea 84: Línea 225:
end
end


function z.ordenar(tabla, funcion)
function z.ordenarFuncion(tabla, funcion)
local funcionInestable = funcion
local funcionInestable = funcion
-- Añadir a la tabla un campo con el orden
-- Añadir a la tabla un campo con el orden
for i,n in ipairs(tabla) do tabla[i].orden = i end
for i,n in ipairs(tabla) do tabla[i].__orden = i end
table.sort(tabla,  
table.sort(tabla,  
Línea 94: Línea 235:
  if    funcionInestable(a, b) then return true -- a < b
  if    funcionInestable(a, b) then return true -- a < b
  elseif funcionInestable(b, a) then return false -- b < a
  elseif funcionInestable(b, a) then return false -- b < a
  elseif a.orden <= b.orden    then return true -- a = b y a aparece antes que b
  elseif a.__orden < b.__orden  then return true -- a = b y a aparece antes que b
  else                              return false -- a = b y b aparece antes que a
  else                              return false -- a = b y b aparece antes que a
  end
  end
    end)
end
)
   
    -- Eliminar de la tabla el campo con el orden
for i,n in ipairs(tabla) do tabla[i].__orden = nil end
end
 
function z.ordenar(tabla, criterio)
if type(criterio) == 'table' then
z.ordenarFuncion(tabla,
function(a,b)
local valorA, valorB
for i,campo in ipairs(criterio) do
valorA = a[campo]
valorB = b[campo]
if not valorA and not valorA then
-- No hacer nada
elseif not valorA and valorB then
return true
elseif valorA and not valorB then
return false
elseif valorA < valorB then
return true
elseif valorA > valorB then
return false
end
end
  return false -- Todos los valores son iguales
end
)
else
z.ordenarFuncion(tabla, criterio)
end
end
 
function z.agrupar(tabla, clave, campo)
local tabla2 = {}
local v2
for k,v in ipairs(tabla) do
if not v[campo] then
table.insert(tabla2, v)
v2 = nil
elseif v2 and v2[clave] == v[clave] then
-- Agrupar
table.insert(v2[campo], v[campo])
else
v2 = v
v2[campo] = {v[campo]}
table.insert(tabla2, v2)
end
end
return tabla2
end
end
   
   
return z
return z

Revisión actual - 11:07 16 jul 2023

Uso

Todas las funciones del módulo se llaman desde Lua.

Funciones

Las funciones son:

tostring(tabla)
Convierte la tabla en una cadena de caracteres.
elemento(tabla, indice1, indice2, ..., indicen)
Devuelve el elemento tabla[indice1][indice2]...[indicen]
en(tabla, valor)
Devuelve la clave del elemento de tabla con ese valor si el elemento pertenece a la tabla.
insertar(tabla, elemento)
Inserta el elemento en la tabla si no está ya incluido.
Parámetros:
  • tabla: Tabla lua. Obligatorio.
  • elemento: Elemento a insertar. Optativo
Valor devuelto: La función devuelve true si el elemento a insertar está informado (no es nil) y false si no se le pasa ningún elemento a insertar.
copiarElementosConValor(tabla)
Devuelve una copia de la tabla eliminando los elementos sin valor
sonIguales(tabla1, tabla2)
Devuelve si las dos tablas son iguales.
ordenar(tabla, función)
Ordena la tabla utilizando la función. Similar a la función sort de table pero es estable.
agrupar(tabla, clave, campo)

ordenar(tabla, función)

Función para ordenar una tabla de forma estable. La función permite además ordenar valores nulos que se sitúan al principio de la tabla ordenada. Por ejemplo, si tenemos:

local moduloTablas = require('Módulo:Tablas') 
  local ordenarTabla = moduloTablas.ordenar

local t = {
  [1] = {
    ["id"] = "Q255032", 
    ["anyo"] = "1965"
  }, 
  [2] = {
    ["id"] = "Q936683", 
    ["anyo"] = "1967"
  }, 
  [3] = {
    ["id"] = "Q1056265", 
    ["anyo"] = "1968"
  }, 
  [4] = {
    ["id"] = "Q1086189", 
    ["anyo"] = "1970"
  }, 
  [5] = {
    ["id"] = "Q549884", 
    ["anyo"] = "1970"
  }, 
  [6] = {
    ["id"] = "Q549884", 
    ["anyo"] = "1971"
  }, 
  [7] = {
    ["id"] = "Q610903", 
    ["anyo"] = "1975"
  }, 
  [8] = {
    ["id"] = "Q1056251", 
    ["anyo"] = "1976"
  }, 
  [9] = {
    ["id"] = "Q3405406", 
    ["anyo"] = "1976"
  }, 
  [10] = {
    ["id"] = "Q3625727", 
    ["anyo"] = "1976"
  }, 
  [11] = {
    ["id"] = "Q898527", 
    ["anyo"] = "1978"
  }, 
  [12] = {
    ["id"] = "Q901462", 
    ["anyo"] = "1981"
  }, 
  [13] = {
    ["id"] = "Q3910469", 
    ["anyo"] = "1987"
  }, 
  [14] = {
    ["id"] = "Q255032", 
    ["anyo"] = "1958"
  }
}

local t2 = ordenarTabla(t, {'id', 'anyo'})

t2 será igual a:

{
  [1] = {
    ["anyo"] = "1976", 
    ["id"] = "Q1056251"
  }, 
  [2] = {
    ["anyo"] = "1968", 
    ["id"] = "Q1056265"
  }, 
  [3] = {
    ["anyo"] = "1970", 
    ["id"] = "Q1086189"
  }, 
  [4] = {
    ["anyo"] = "1958", 
    ["id"] = "Q255032"
  }, 
  [5] = {
    ["anyo"] = "1965", 
    ["id"] = "Q255032"
  }, 
  [6] = {
    ["anyo"] = "1976", 
    ["id"] = "Q3405406"
  }, 
  [7] = {
    ["anyo"] = "1976", 
    ["id"] = "Q3625727"
  }, 
  [8] = {
    ["anyo"] = "1987", 
    ["id"] = "Q3910469"
  }, 
  [9] = {
    ["anyo"] = "1970", 
    ["id"] = "Q549884"
  }, 
  [10] = {
    ["anyo"] = "1971", 
    ["id"] = "Q549884"
  }, 
  [11] = {
    ["anyo"] = "1975", 
    ["id"] = "Q610903"
  }, 
  [12] = {
    ["anyo"] = "1978", 
    ["id"] = "Q898527"
  }, 
  [13] = {
    ["anyo"] = "1981", 
    ["id"] = "Q901462"
  }, 
  [14] = {
    ["anyo"] = "1967", 
    ["id"] = "Q936683"
  }
}

agrupar(tabla, clave, campo)

Función para agrupar los elementos de la tabla con la misma clave. La tabla debe ordenarse previamente. En el ejemplo anterior el código:

  local agruparTabla = moduloTablas.agrupar

local t3 = agrupar(t2, 'id', 'anyo')

hará que la tabla t3 valga:

{
  [1] = {
    ["anyo"] = {
      [1] = "1976"
    }, 
    ["id"] = "Q1056251"
  }, 
  [2] = {
    ["anyo"] = {
      [1] = "1968"
    }, 
    ["id"] = "Q1056265"
  }, 
  [3] = {
    ["anyo"] = {
      [1] = "1970"
    }, 
    ["id"] = "Q1086189"
  }, 
  [4] = {
    ["anyo"] = {
      [1] = "1958", 
      [2] = "1965"
    }, 
    ["id"] = "Q255032"
  }, 
  [5] = {
    ["anyo"] = {
      [1] = "1976"
    }, 
    ["id"] = "Q3405406"
  }, 
  [6] = {
    ["anyo"] = {
      [1] = "1976"
    }, 
    ["id"] = "Q3625727"
  }, 
  [7] = {
    ["anyo"] = {
      [1] = "1987"
    }, 
    ["id"] = "Q3910469"
  }, 
  [8] = {
    ["anyo"] = {
      [1] = "1970", 
      [2] = "1971"
    }, 
    ["id"] = "Q549884"
  }, 
  [9] = {
    ["anyo"] = {
      [1] = "1975"
    }, 
    ["id"] = "Q610903"
  }, 
  [10] = {
    ["anyo"] = {
      [1] = "1978"
    }, 
    ["id"] = "Q898527"
  }, 
  [11] = {
    ["anyo"] = {
      [1] = "1981"
    }, 
    ["id"] = "Q901462"
  }, 
  [12] = {
    ["anyo"] = {
      [1] = "1967"
    }, 
    ["id"] = "Q936683"
  }
}

local z = {}

-- Código copiado de http://lua-users.org/wiki/SortedIteration
function __genOrderedIndex( t )
    local orderedIndex = {}
    for key in pairs(t) do
        table.insert( orderedIndex, key )
    end
    table.sort( orderedIndex )
    return orderedIndex
end

function orderedNext(t, state)
    -- Equivalent of the next function, but returns the keys in the alphabetic
    -- order. We use a temporary ordered key table that is stored in the
    -- table being iterated.

    local key = nil
    --print("orderedNext: state = "..tostring(state) )
    if state == nil then
        -- the first time, generate the index
        t.__orderedIndex = __genOrderedIndex( t )
        key = t.__orderedIndex[1]
    else
        -- fetch the next value
        for i = 1,table.getn(t.__orderedIndex) do
            if t.__orderedIndex[i] == state then
                key = t.__orderedIndex[i+1]
            end
        end
    end

    if key then
        return key, t[key]
    end

    -- no more value to return, cleanup
    t.__orderedIndex = nil
    return
end

function orderedPairs(t)
    -- Equivalent of the pairs() function on tables. Allows to iterate
    -- in order
    return orderedNext, t, nil
end

function z.tostringordered(tabla, identacion)
    identacion = identacion or '\n'
    local identacion2 = identacion .. '  '
    
    if not tabla then
    	return
    end
    
    local valores = {}
    local k2, v2
 
    for k,v in orderedPairs(tabla) do
    	if type(k) == 'string' then
    		k2 = '"' .. k .. '"'
    	else
    		k2 = k
    	end
        if type(v) == 'table' then
            v2 = z.tostringordered(v, identacion2)
        elseif type(v)=='string' then
        	v2 = '"' .. v .. '"'
        else
        	v2 = tostring(v)
        end
        
        table.insert(valores, '[' .. k2 .. '] = ' .. v2)
    end
 
    return '{' .. identacion2 .. (table.concat(valores, ', ' .. identacion2) or '') .. identacion .. '}'
end

function z.tostring(tabla, identacion)
    identacion = identacion or '\n'
    local identacion2 = identacion .. '  '
    
    if not tabla then
    	return
    end
    
    local valores = {}
    local k2, v2
 
    for k,v in pairs(tabla) do
    	if type(k) == 'string' then
    		k2 = '"' .. k .. '"'
    	else
    		k2 = k
    	end
        if type(v) == 'table' then
            v2 = z.tostring(v, identacion2)
        elseif type(v)=='string' then
        	v2 = '"' .. v .. '"'
        else
        	v2 = tostring(v)
        end
        
        table.insert(valores, '[' .. k2 .. '] = ' .. v2)
    end
 
    return '{' .. identacion2 .. (table.concat(valores, ', ' .. identacion2) or '') .. identacion .. '}'
end

function z.elemento(tabla, indice1, indice2, indice3, indice4, indice5, indice6, indice7)
	local resultado
	
	if not tabla or not indice1 then
		return
	end
	
	resultado = tabla[indice1]
	
	if not indice2 or not resultado then
		return resultado
	end
	
	resultado = resultado[indice2]

	if not indice3 or not resultado then
		return resultado
	end
	
	resultado = resultado[indice3]
	
	if not indice4 or not resultado then
		return resultado
	end
	
	resultado = resultado[indice4]
	
	if not indice5 or not resultado then
		return resultado
	end
	
	resultado = resultado[indice5]
	
	if not indice6 or not resultado then
		return resultado
	end
	
	resultado = resultado[indice6]
	
	if not indice7 or not resultado then
		return resultado
	end
	
	resultado = resultado[indice7]
	
	return resultado
end

function z.en(tabla, elemento)
    if not elemento then
        return
    end
    for k,v in pairs( tabla ) do
        if v == elemento then
            return k
        end
    end
end

function z.copiarElementosConValor(original)
	local copia= {}
	
    for k,v in pairs(original) do
        if v~='' then
            copia[k] = original[k]
        end
    end	
    
    return copia
end

function z.insertar(tabla, elemento)
	if not elemento then
		return false
	end

	if not z.en(tabla, elemento) then
		table.insert(tabla, elemento)	
	end
	
	return true
end

function z.insertarElementosConValor(origen, destino)
    for k,v in pairs(origen) do
        if v~='' then
            table.insert(destino, v)
        end
    end	
    
    return copia
end

function z.sonIguales(tabla1, tabla2)
	if not tabla1 or not tabla2 then
		return false
	end
	
	if tabla1 == tabla2 then
		return true
	end
	
	for k,v in pairs(tabla1) do
		if tabla2[k] ~= v then
			return false
		end
	end

	for k,v in pairs(tabla2) do
		if not tabla1[k] then
			return false
		end
	end

	return true
end

function z.ordenarFuncion(tabla, funcion)
	local funcionInestable = funcion
	
	-- Añadir a la tabla un campo con el orden
	for i,n in ipairs(tabla) do tabla[i].__orden = i end
	
	table.sort(tabla, 
		function(a,b) 
		   if     funcionInestable(a, b) then return true -- a < b
		   elseif funcionInestable(b, a) then return false -- b < a
		   elseif a.__orden < b.__orden  then return true -- a = b y a aparece antes que b
		   else                               return false -- a = b y b aparece antes que a
		   end
		end
	)
    
    -- Eliminar de la tabla el campo con el orden
	for i,n in ipairs(tabla) do tabla[i].__orden = nil end
end

function z.ordenar(tabla, criterio)
	if type(criterio) == 'table' then
		z.ordenarFuncion(tabla,
			function(a,b)
				local valorA, valorB
				for i,campo in ipairs(criterio) do
					valorA = a[campo]
					valorB = b[campo]
					if not valorA and not valorA then
						-- No hacer nada
					elseif not valorA and valorB then
						return true
					elseif valorA and not valorB then
						return false
					elseif valorA < valorB then
						return true
					elseif valorA > valorB then
						return false 
					end
				end	
		   		return false -- Todos los valores son iguales
			end
		)	
	else
		z.ordenarFuncion(tabla, criterio)
	end
end

function z.agrupar(tabla, clave, campo)
	local tabla2 = {}
	
	local v2
	
	for k,v in ipairs(tabla) do
		if not v[campo] then
			table.insert(tabla2, v)
			v2 = nil
		elseif v2 and v2[clave] == v[clave] then
			-- Agrupar
			table.insert(v2[campo], v[campo])
		else
			v2 = v
			v2[campo] = {v[campo]}	
			table.insert(tabla2, v2)
		end
	end
	
	return tabla2
end
 
return z