jtarchie/underscore-lua

flatten table

vertti opened this issue · 7 comments

__.flatten({{a = 1}, {b = 2}}, true)

expected

{ a = 1, b = 2 }

but got the unchanged original:

{{a = 1}, {b = 2}}

The reason this doesn't work is because shallow currently only works against arrays and not objects. I tried to stay compliant with the original underscoreJS library, which has this current functionality. If you still feel that this is a bug, would should start a dialog/issue with underscoreJS library.

There is also the issue of collision. What do you do when the objects have the same keys? Is a merge from the right or the left?

_.flatten({{a = 1}, {a = 2}}, true) == {a=1}
-- or
_.flatten({{a = 1}, {a = 2}}, true) == {a=2}

@vertti Actually you can work around the problem by changing a single line in _.flatten implementation.

function _.flatten(list, shallow, output)
  output = output or {}
  _.each(list, function(value)
    if type(value)=='table' then
      if shallow then
        _.each(value, function(v) table.insert(output, v) end)
      else
        _.flatten(value, false, output)
      end
    else
      table.insert(output, value)
    end
  end)

  return output
end

In case two subtables have the same keys, the latter wins here, of course.

@jtarchie I think you shouldn't aim to a one-to-one port of Underscore. You have to consider what is idiomatic Lua or you will leave the ported library feel crippled on the new language. And your port actually works much better with non-array table's than the 3 year old port I was using before I found yours.

What would be the best way to solve this, I don't have a great answer for that. Maybe collision behavior could be configurable with similar extra parameters than shallow is now? But I do feel that you should aim for compatibility with non-array tables as much as possible or you'll lose a lot of potential for use in Lua.

Anyways, thank you for your work on this!

I'd like to mention that this is basically what I tried to do in my personal library, Moses. It was also inspired by Underscore (as well as its companion Allen, which is unfinished, yet).

@Yonaba Thanks, I'll take a peek :)

@Yonaba actually that flatten does not handle those cases. With the shallow set to true, the library iterates through anything that is a table and adds its values to the output. There are actually two different patterns here, one for array of values and another for array key-value pairs.

@vertti that's not to say I don't agree with you. Does #extend provide the same functionality you are looking for?

_.extend({a=1},{b=2}) == {a=1,b=2}