1

I am trying to write a helper method to find the intersection of two hashes/Objects like this...

Object::intersect = (obj)->
  t = {}
  t[k] = @[k] for k of obj 
  t

x = { a: 1, b: 2, c: 3 }
w = { a: true, b: 3 }
x.intersect(w) #=> { a: 1, b: 2, intersect: [Function] }

the results are as I expected/wanted EXCEPT for the addition of 'intersect' key/value.

What am I missing here?

1
  • If w = { a: true, b: 3, d: 4}, then d: undefined appears in the result. Commented May 15, 2014 at 20:49

2 Answers 2

1

Your property is enumerable, that's why it appears in both objects when you iterate.

A solution would be this :

Object.defineProperty Object.prototype, 'intersect', value:(obj)->
  t = {}
  t[k] = @[k] for k of obj
  t

Demonstration (compiled as JS)

But modifying objects you don't own, especially Object is terrible practice and can lead to many unexpected problems for other coders. Read Maintainable JavaScript: Don’t modify objects you don’t own.

Here it would be as easy and so much cleaner to simply define a function taking two objects as arguments...

Sign up to request clarification or add additional context in comments.

4 Comments

I understand about not modifying objects you don't own. Our development group continues to debate it. Even so, I prefer syntax of a.intersect(b) over intersect(a,b). In support of your point about OYDO - if I had written it intersect = (a,b)-> t={};(t[k] = a[k] for k of b);t I never would have raised the question. sigh. Many thanks!
@Paul I hope you'll finally settle for not modifying the prototype of Object, Array, and so on. It feels smart at first but really isn't wise.
There are some browser compatibility issues with defineProperty. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
The prototype= intersect is both enumerable and writeable (using the defineProperty options).
1

Adding the 'ownProperty' check removes this intersect property

Object::intersect= (obj) ->
  t = {}
  t[k] = @[k] for own k of obj
  t

coffee> x = {a:1, b:2, c:3}; w = {a:true, b:3}
{ a: true, b: 3 }
coffee> x.intersect(w)
{ a: 1, b: 2 }

If w has keys that are not in x, they will appear in the result with an undefined value.

A more robust function could be constructed from underscore

_ = require 'underscore'
_.pick(x, _.keys(w))

1 Comment

This fixes it here, but the problem of having an enumerable function on all objects will be present elsewhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.