0

The main objective is to filter duplicate items from an array by any given property. The solution I'm trying to use is in js @ https://stackoverflow.com/a/31194441/618220

I tried to implement it in coffeescript. It is all good, except the scoping of the functions. I don't want _indexOfProperty function to be called from outside - since it is useless in all other contexts. But if I make it private (by removing @ in declaration), I cannot call it from within inputArray.reduce

My coffee code looks like this:

Utils = ->
    @filterItemsByProperty= (inputArray,property)=>
        if not _.isArray inputArray
            return inputArray
        r = inputArray.reduce(((a,b,c,d,e)=>
                if @._indexOfProperty(a,b,property) < 0
                    a.push(b)
                a
            ),[])
        r

    @_indexOfProperty= (a,b,prop) ->
        i = 0
        while i< a.length
            if a[i][prop] == b[prop]
                return i
            i++
        -1

    return

window.utils = Utils

here's how I invoke it from other places:

App.utils.filterItemsByProperty(personArray,"name")

And right now, anyone can do this as well:

App.utils._indexOfProperty(1,2,3)

How to modify the coffee to stop this ?

Community
  • 1
  • 1
MrClan
  • 6,402
  • 8
  • 28
  • 43

2 Answers2

2

Just don't put _indexOfProperty on this / @ and it won't be visible:

Utils = ->
    _indexOfProperty = (a,b,prop) ->
        i = 0
        while i< a.length
            if a[i][prop] == b[prop]
                return i
            i++
        -1

    @filterItemsByProperty= (inputArray,property)=>
        if not _.isArray inputArray
            return inputArray
        r = inputArray.reduce(((a,b,c,d,e)=>
                if _indexOfProperty(a,b,property) < 0
                    a.push(b)
                a
            ),[])
        r

    return

window.utils = Utils
ccg
  • 313
  • 2
  • 8
  • Thanks, it worked, and I'm surprised. As already mentioned in the question, I know that removing @ will make the function private. But I'm unable to figure out why I could not access it from within .reduce earlier today? Will have to check tomorrow. – MrClan Sep 14 '15 at 14:37
  • @MrClan sorry, I must have read over it. Probably you still had the `@` symbol in your reducer function or you might have had a typo :) – ccg Sep 14 '15 at 14:46
0

Can you please remove the '@', and this time define a local variable "indexOfProperty" within filterItemsByProperty scope and assign to it "_indexOfProperty" (that way you can use "indexOfProperty" within reduce())?

@filterItemsByProperty = (inputArray, property) ->
    indexOfProperty = _indexOfProperty
    if !_.isArray(inputArray)
      return inputArray
    r = inputArray.reduce(((a, b, c, d, e) ->
      if indexOfProperty(a, b, property) < 0
        a.push b
        a
      ), [])
    r
natdico
  • 863
  • 6
  • 11