HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Refactor array for loop result

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
resultarrayloopforrefactor

Problem

types = [
    { name: "Feature"}
    { name: "Enhancement"}
    { name: "Bug"}
    { name: "Spike"}
  ]

buildIndex = (source, property) ->
  array = []
  array[prop[property]] = prop for prop in source
  array

buildIndex types, 'name'


Result:

[Feature: Object, Enhancement: Object, Bug: Object, Spike: Object]
  Bug: Object
  Enhancement: Object
  Feature: Object
    name: "Feature" 
  Spike: Object


This is my ugly code. How to refactor this? My problem is the buildIndex function. Iyt works, but it isn't elegant.

Solution

There's something fishy here. You're creating an array, but you're not using it as one. You're simply adding named properties to it, like you can with any object. In the end, you're left with an array that still has a length of zero. So I'm betting you don't actually want an array at all.

And in that case, I'd rewrite it to this

buildIndex = (source, property) ->
  obj = {}
  obj[prop[property]] = prop for prop in source
  obj


No more array-nonsense. However, if this is indeed what you're going for, then that's pretty much it. I agree it doesn't look particularly elegant, but it's about as good as it gets with basic CoffeeScript.

However, you could use reduce, if you're targeting browsers that support it (or Node.js):

buildIndex = (source, property) ->
  source.reduce (obj, item) ->
    obj[item[property]] = item
    obj
  , {}


but as you can see, the callback-first style of reduce means you end up with a dangling comma and argument instead, which isn't terribly neat either.

Alternatively, if you're using something like underscore.js, you can use a groupBy function to do this for you

buildIndex = (source, property) ->
  _.groupBy source, (item) -> item[property]


Looks better, although it's merely hiding the same code as above.

Code Snippets

buildIndex = (source, property) ->
  obj = {}
  obj[prop[property]] = prop for prop in source
  obj
buildIndex = (source, property) ->
  source.reduce (obj, item) ->
    obj[item[property]] = item
    obj
  , {}
buildIndex = (source, property) ->
  _.groupBy source, (item) -> item[property]

Context

StackExchange Code Review Q#41822, answer score: 2

Revisions (0)

No revisions yet.