Circularity

Objects as Dictionaries

Comparing and Copying Objects

Write a function copy(obj), which duplicates an object (not just copying a reference to it). You only need a shallow copy, duplicating only the top level of properties. That is, if obj contains another object inner, the duplicate may share a reference to inner rather than copying all of inner too.

Write another function to compare two objects:
equal(objA,objB) should return true only when objA and objB have exactly the same properties with the same values. You only need shallow equality: if objA and objB each have a property inner referring to an object, check only that both inner objects are identical (references to the same object); don't try to compare their properties.
Note that two empty objects should be considered equal (by this function, not by the == operator).

Write a third function:
similar(objA,objB) should return true only when objA and objB have exactly the same properties, regardless of their values.

Combining Objects as Sets

We can interpret objects as sets of properties, and merge those sets in various ways. Write a function for each of the following merges:

Union: The union of objects A,B is a new object which contains all the properties found in either A or B. If a property is found in both, the merged property gets the shared key and the value (A[key] || B[key]).
For example: the union of {a:1,b:0} and {a:0,c:0} is {a:1,b:0,c:0}.

Implement function union(objA,objB).

Intersection: The intersection of objects A,B is a new object which contains only those properties found in BOTH A and B. The value of each intersecting property is (A[key] && B[key]).
For example, the intersection of {a:1,b:0} and {a:0,c:0} is {a:0}.

Implement function intersect(objA,objB).

Subtraction: The subtraction of B from A, aka "A minus B", is an object which contains all the properties of A which are NOT in B. Note that this merge is usually not symmetric: A minus B doesn't equal B minus A (except in one case, which you should identify!)
For example, {a:1,b:0} minus {a:0,c:0} is {b:0}, and the reverse subtraction is {c:0}.

Implement function subtract(objA,objB).

Each function should return a new object, or undefined if either of their arguments is not an object.

Data Structure Example: Chores!

Below is a toy data-structure which uses "dictionary" objects to represent a relationship between two sets: which family members are responsible for which household chores.

In all of the challenges below, your code should remain as generic as possible, able to work with any similar table of people and jobs. Therefore your code should not contain any reference to particular people or particular jobs. You may refer to the variables people and jobs but not the variables for individual person and chore objects (mom, dry, etc).

As well as you can, in collaboration with your team, sketch all the objects involved in the structure and the connections between them.

Write a function hasJob(personName,jobName) returning true or false.
Here's an example of how it would be used:

hasJob('mom','mop') --> true
hasJob('mom','dry') --> false

Now write a variant, hasJob(personObj,jobObj), which receives objects instead of strings:

hasJob(mom,mop) --> true
hasJob(mom,dry) --> false

Write a function peopleDoing(job) which returns an array of people-objects. Allow parameter job to be either an object or a job name.