Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_.transform Applies a function to perform transformation on the object #1112

Closed
wants to merge 3 commits into from
Closed

Conversation

ming-codes
Copy link

The goal is to supply a function to work with the object itself. Most underscore functions work with collections and treats objects as only associative array. #1068 may be related, but that pull request still work the object as an associative array.

The main use case is during chaining that you'll want to apply a certain function to the wrapped object.

// The goal of this snippet is to select cells in table,
// do filter on them, then wrap it back as a jQuery object
_.chain($('td')) // One of the great thing about underscore is
                     // that it work with any array-like object
  .groupBy('cellIndex')
  .sortBy(function(__, key) {
    return Number(key)
  })
  .first()
  .transform($)
  .value()
  .css('background-color', 'red')

Alternative solution without _.transform may be ugly because it disrupts the structure flow.

$(_.chain($('td'))
  .groupBy('cellIndex')
  .sortBy(function(__, key) {
    return Number(key)
  })
  .first())
  .value()
  .css('background-color', 'red')

Naming-wise, it may be more appropriate to call it apply. But since the _ object is itself a function and we don't want to override Function.prototype.apply, I came up with the transform alternative.

Alternatively, the functionality may be merged with either _.chain().value(function) or _.tap(function) by making the chain returns tap's function return value if it does return something. Something like this

_.tap = function(obj, inter) {
  return inter(obj) || obj
}

@jashkenas
Copy link
Owner

Very interesting. This is only useful in the middle of a _.chain, correct?

@ming-codes
Copy link
Author

@jashkenas While that is true, I like to think of it as playing friendly with other libraries. :)

Also, before this, the only way to apply your own function on the wrapped object while still keeping it under wrap is through _.mixin. This may not be the optimal solution when the function you want to apply is a curried function.

@ming-codes
Copy link
Author

But that would mask the other map, and they do have the same signature.

On Jun 20, 2013, at 6:59 AM, "Mario T. Lanza" [email protected] wrote:

transform is essentially map applied to a single object. Perhaps it makes sense to use the term map for consistency?


Reply to this email directly or view it on GitHub.

@jdalton
Copy link
Contributor

jdalton commented Jun 20, 2013

I think the name passthru is more descriptive.

@ming-codes
Copy link
Author

@mlanza _.map is already overloaded to accept either an array or hash object. I don't know how you can overload it more without adding another flag param

http://underscorejs.org/#map

I'm liking _.passthru best so far. It appropriately describes what it do without name clashing with other functions.

@jdalton
Copy link
Contributor

jdalton commented Jun 21, 2013

The reason passthru is a better choice is because the func function doesn't necessarily have to transform the value passed to it. For example:

// the number is passed thru `Object` and converted to an object
_(2).chain().passthru(Object).isObject().value(); // true

// the object is passed thru `Object` and returned unmodified
_({a: 1}).chain().passthru(Object).isObject().value(); // true

@jashkenas
Copy link
Owner

Neat. I don't think it's quite useful enough to merit the complexity of explaining how to use it.

Most of the time, to transform, you'll want to map in the middle of your chain to do so. In cases like this, where you've called first, or want to transform the entire collection, it's not too bad to break out of the chain to do so.

@jashkenas jashkenas closed this Jul 6, 2013
@ming-codes
Copy link
Author

For anyone that's still looking for this function, lodash now has it.

http://lodash.com/docs#transform

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants