Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Im wondering if there is a cleaner way to write this -

map = (obj) ->
  $scope.data.push({name : obj.name, id : obj.id})
map obj for obj in objArr      

Specifically, I'm wondering if I can anonymize the map function.

share|improve this question
    
could you provide more context code please? –  Malachi Oct 3 '14 at 21:26
    
@Malachi I could.. but do you really need it? I thought this was a rather self contained question. –  David Grinberg Oct 3 '14 at 21:26
    
there isn't much to review here, just not sure we can help make this any cleaner, I almost said it could use a semi-colon and brackets, but I don't remember if CoffeeScript needs them... –  Malachi Oct 3 '14 at 21:28
    
@Malachi CoffeeScript does not need them. I'm specifically asking about the index variable i though. Is it possible to get rid of it via a different function? –  David Grinberg Oct 3 '14 at 21:28
    
I am not sure, you will have to wait for one of the more veteran Javascript people to take a look at this. –  Malachi Oct 3 '14 at 21:30

1 Answer 1

I'd certainly do something about that function too. It's called map, yet doesn't behave like a map function usually does (i.e. it doesn't return an array). Instead it causes side-effects, so it's a very misleading function.

But you can just do everything in the loop without introducing a function:

$scope.data.push {name: obj.name, id: obj.id} for obj in objArr

or, in a more readable fashion:

for obj in objArr
  $scope.data.push {name: obj.name, id: obj.id}

That's really just your code but unwrapped to get rid of the function.

You could also keep the function if you often need the name/id subset, but then have it only map to a new array. Then you can go about glueing that to $scope.data (using $scope.data.push(array...) or $scope.data = $scope.data.concat(array)).

Heck, you can even do that as a one-liner, though it's a little too obtuse to really recommend:

$scope.data.push ({name: obj.name, id: obj.id} for obj in objArr)...

Alternatively, you may use CoffeeScript's shorthand syntax for object literals and object destructuring:

for obj in objArr
  {name, id} = obj            # grab the name and id properties as local vars
  $scope.data.push {name, id} # push an object with implicitly-named properties

It'd be neat if you could combine those into a single expression (aka slice for objects), but as far as I know, there's no eloquent way to do that.

Many general purpose utility libraries have something like this, though. For instance, Underscore has _.pick. However, it's also easy to write your own, if you need it often:

pick = (object, properties...) ->
  result = {}
  result[prop] = object[prop] for prop in properties
  result

In which case you do stuff like:

for obj in objArr
  $scope.data.push pick(obj, 'name', 'id)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.