[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
**Subject**: **Re: Iterating pairs of keys from a table**
**From**: Dirk Laurie <dirk.laurie@...>
**Date**: Tue, 28 Feb 2017 10:24:49 +0200

2017-02-28 5:38 GMT+02:00 Tim Hill <drtimhill@gmail.com>:
> I recently had a need to iterate table key combinations in pairs. For example, for a table with keys (not values) of {a, b, c, d}, I wanted to iterate:
>
> (a,b), (a,c), (a,d), (b,c), (b,d), (c,d)
>
> That is, I wanted unique combinations (not permutations) of non-identical keys. Sort order was not important.
>
> Anyway, I came up with this generator function:
>
> function keypairs(t)
> local s = next(t)
> local n, i = next(t, s), s
> return function()
> i = next(t, i)
> if i == nil then
> s, n = n, next(t, n)
> i = n
> if i == nil then s = nil end
> end
> return s, i
> end
> end
>
> Example use:
>
> t = { a=true, b=true, c=true, d=true }
> for k1, k2 in keypairs(t) do
> print(k1, k2)
> end
>
> However, I was wondering if anyone has a better (faster? smaller? cleaner?) solution they would like to share (or have I missed something very obvious in Lua?). I poked around in the archives and didn’t find anything, but it’s quite possible my limited search missed something.
>
> (The only tweak I thought of was to swap the return order of s and i, which would make the nested “if” unnecessary. However I liked the fact that as written the generator returns the pairs in (major, minor) order that matches that returned by pairs().)
One could use a coroutine. That saves a lot of bookkeeping.
keypairs = function(tbl)
return coroutine.wrap(
function()
for k in next,tbl do
for m in next,tbl,k do
coroutine.yield(k,m)
end
end
end)
end