Reputation: 89
The question was when given multiple arrays return an array with all intersected array values. I have read through a few solutions and I am trying to understand this hash table solution.
I am having trouble understanding this line:
a[propName] = a[propName] || {count:0, value: val};
To my understanding we are looping through each element of our subarray. Our accumulator object is given the property name of the subarrays value.
This is where I get confused. The value of our object property is a[propName]. I do not understand this value. My understanding is we should make our object property the value of our subarray (making the line a[propName]=a[propName]
into a[propName]=propName
instead) but when I do this we are not able to count how many times the property has occurred. I do not get why we have to put the a[propName]
and what data structure we are accessing that is different from just using propName
. There obviously a difference since when I use a[propName]
we are able to count how many times the property has occurred. If someone can thoroughly explain what is going on I'd be very grateful.
function intersection(){
// convert arguments to array of arrays
var arrays = [].slice.call(arguments);
// create an object that tracks counts of instances and is type specific
// so numbers and strings would not be counted as same
var counts= arrays.reduce(function(a,c){
// iterate sub array and count element instances
c.forEach(function(val){
var propName = typeof val + '|' + val;
// if array value not previously encountered add a new property
a[propName] = a[propName] || {count:0, value: val};
// increment count for that property
a[propName].count++;
console.log(a);
});
return a;
},{});
// iterate above object to return array of values where count matches total arrays length
return Object.keys(counts).reduce(function(resArr, propName){
if(counts[propName].count === arrays.length){
resArr.push(counts[propName].value);
}
return resArr;
},[]);
}
Upvotes: 2
Views: 93
Reputation: 7360
The line you are pointing checks if a[propName]
exists, and, if it not exists (so it is undefined
) initialize it to {count:0, value: val};
.
Let's have a closer look.
First of all, let's use more meaningful names. a
is accumulator
, the variable you use to keep track of everything.
At the beginning, it is an empty object.
At the first iteration of c.forEach
it has no properties.
Therefore, given a propName like 'string|asd', it adds its first property, and accumulator
becomes accumulator = {'string|asd' : {count:0, value: val}};
.
Then increments the value of count.
If it finds another 'string|asd' it just increments the count, because the check a[propName] = a[propName] || {count:0, value: val};
will just keep the prop.
let a = {}
// a.c does not exist, therefore is undefined
console.log(a.c)
a.c = a.b || 1;
// a.c now is 1
console.log(a.c)
a.c = a.c || 2;
// a.c is still 1, because the `or` operator returns as soon as it finds a valid value
console.log(a.c)
Upvotes: 1