local _M = {}

function _M.keys(t)
  local keys = {}
  for key,_ in pairs(t) do
    table.insert(keys, key)
  end
  return keys
end

function _M.count(t)
  local count = 0
  for key,_ in pairs(t) do
    count = count + 1
  end
  return count
end

function _M.first(t)
  for key,val in pairs(t) do
    return key,val
  end
end

function _M.merge(...)
	local arg = {...}
	if not arg[1] then return nil end
	for i,v in ipairs(arg) do
		for key,val in pairs(arg[i]) do
			arg[1][key] = val
		end  
	end
	return arg[1]
end

function _M.sort(t)
	table.sort(t)
	return _M.values(t)
end

function _M.values(t)
	local results = {}
	for k,v in pairs(t) do
		table.insert(results,v)
	end
	return results
end

function _M.sort_by_keys(t)
	local keys = {}
	local results = {}
	for k,v in pairs(t) do
		table.insert(keys,k)
	end
	table.sort(keys)
	for k,v in pairs(keys) do
		table.insert(results,t[k])
	end
	return results
end

function _M.ordnung(t)
  local res = {}
  for key,val in pairs(t) do
	if val.order then 
		res[val.order] = {}
		res[val.order][key] = val 
	else table.insert(res,t[key]) end
  end
  return res
end

function _M.minkey(t)
    local a = {}
    for n in pairs(t) do table.insert(a, n) end
    table.sort(a)
	return a[1]
end

function _M.in_array(t,val)
    for _,v in ipairs(t) do 
		if v == val then return true end
	end
	return false
end

function _M.implode(t,before,after,sep)
  local result = ''
  local count = _M.count(t)
  for key,val in pairs(t) do  
	result = result..before..val..after
	if key < count then result = result..sep end
  end
  return result
end

function _M.binary_search(arr, target)
  local left = 1
  local right = #arr
  while left <= right do
    local mid = math.floor((left + right) / 2)
    if arr[mid] == target then
      return mid
    elseif arr[mid] < target then
      left = mid + 1
    else
      right = mid - 1
    end
  end
  return nil
end

function _M.explode(t,delimiter)
  local result = { }
  local from  = 1
  local delim_from, delim_to = string.find(t, '%'..delimiter, from  )
  while delim_from do
    table.insert( result, string.sub(t, from , delim_from-1 ) )
    from  = delim_to + 1
    delim_from, delim_to = string.find(t, '%'..delimiter, from  )
  end
  table.insert( result, string.sub(t, from  ) )
  return result
end

function _M.clear(t)
	local result = {}
	for key,data in pairs(t) do	
		if data ~= nil then table.insert(result,data) end		
	end
	return result
end

function _M.blank(t,default)
	local results = {}
	for _,v in ipairs(t) do
		results[''..v] = default
	end
	return results
end

return _M
