Log In  

This isn't really anything special, just a little quality of life improvement I've found handy and keep in a file of utility functions I use frequently.

Overloads sub() so it works on arrays as well as strings. I find it useful to be able to slice and dice arrays in the same way as strings and especially now that we can index strings with square bracket notation the difference between them isn't always important. I've got something with a length and I want a sub-section of it. Makes sense to use the same function for both, in my mind at least.

_sub = sub

function sub(lst, i, j)
   if type(lst) == 'string' then
      return _sub(lst, i, j)
   else
      local r = {}
      for n=i,j or #lst do
         add(r, lst[n])
      end
      return r
   end
end

Creates a new array without modifying the original. Doesn't handle negative indices because I've not really needed them so far but it would be easy enough to add.

Potentially a feature suggestion @zep? I don't mind writing the function myself but I'd also be happy not to. But maybe I'm the only one who finds it useful.

P#120538 2022-11-12 13:15

I'm confused, @jasondelaat.

Could you please post an example to show this in action ?

P#120556 2022-11-12 19:13

@dw817

Sure.
Right now sub() only works on strings.

print(sub('abcde', 2, 4))     -- prints: bcd
print(sub({1,2,3,4,5}, 2, 4)) -- prints nothing, sub() returns [nil]
                              -- for anything other than strings

This overloads sub() so it still works the same for string but it'll do the same thing for arrays.

print(sub('abcde', 2, 4))     -- prints: bcd
lst = sub({1,2,3,4,5}, 2, 4)
print(lst)                    -- prints: [table]
print(lst[1])                 -- 2
print(lst[2])                 -- 3
print(lst[3])                 -- 4

One way to use it would be in a loop if you only want to loop over part of the contents of an array.

lst = {1, 2, 3, 4, 5}
for l in all(sub(lst, 3)) do
    print(l)
end

Which will print 3, 4, and 5.

Obviously you could just do it with a loop counter but, in my opinion, that's messier.

lst = {1, 2, 3, 4, 5}
for i=3,#lst do
    print(lst[i])
end

I prefer the former to the latter from a readability perspective but that's just personal preference.

That's a simple example and not exactly worth all the extra tokens but I tend to think of almost everything as just lists of stuff so the more ways I have to manipulate lists and parts of lists the better. Basically if you can think of a reason why you might want to be able to extract a substring from a larger string, I probably have similar reasons to want to be able to extract a sub-array from a larger array.

The other thing is that if I have some variable that might be a string or might be an array and I want a sub-sequence out of it, I don't have to care what its actual type is. With normal sub() I'd have to waste tokens checking the type so I could extract the sequence in an appropriate way and I'd have to do that every time that situation came up. Admittedly that's probably not super often. But this way that type check lives in sub() and I don't ever have to worry about it again.

P#120567 2022-11-12 22:04

If I'm understanding you correctly, @jasondelaat, having seen your demo, you want to use sub() for advanced array access.

While I may never need this myself as I'm old school, I can definitely see this useful for advanced and ace programmers.

P#120587 2022-11-13 04:07

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 16:03:16 | 0.028s | Q:16