I am looking for a way to know if an array contains all elements with distinction.
For example, b.containsDistinct(a) would return true and c.containsDistinct(a) would return false.
a = [1, 1, 1, 2]
b = [1, 2, 1, 1, 3] // return true
c = [1, 2, 3] // return false
The solutions I could find were only a.every(i => b.indexOf(i) !== -1)
but there are not working for the situation where the elements are the same
How would you solve that ?
3 Answers 3
You could count the values and check if the count is zero or smaller.
function distinct(a, b) {
var counts = {};
a.forEach(v => counts[v] = (counts[v] || 0) + 1);
b.forEach(v => counts[v] = (counts[v] || 0) - 1);
return Object.values(counts).every(count => count <= 0);
}
console.log(distinct([1, 1, 1, 2], [1, 2, 1, 1, 3]));
console.log(distinct([1, 1, 1, 2], [1, 2, 3]));
Comments
You can make use of hashmap
which can be easily implemented by an array in javascript.
let a = [1, 1, 1, 2]
let b = [1, 2, 1, 1, 3] // return true
let c = [1, 2, 3] // return false
Array.prototype.containsDistinct = function(a){
let map1 =[];
this.forEach((val)=>{
if(map1[val] === undefined){
map1[val] = 1;
}
else{
map1[val]+=1;
}
})
let map2 = [];
a.forEach((val)=>{
if(map2[val] === undefined){
map2[val] = 1;
}
else{
map2[val]+=1;
}
})
let flag = true;
map2.forEach((val,key)=>{
if(map1[key] === undefined){
flag = false
}
else if(map1[key]!== map2[key]){
flag = false;
}
})
return flag;
}
console.log(b.containsDistinct(a));
console.log(c.containsDistinct(a));
Comments
My approach is to first calculate the distributions of all the values in both arrays and then check, that every value from the first array occurs in the second array the same or smaller amount of times.
let a = [1, 1, 1, 2];
let b = [1, 2, 1, 1, 3];
let c = [1, 2, 3];
function getDistribution(A) {
return A.reduce(
(distr, v) => ({ ...distr, [v]: distr[v] ? distr[v] + 1 : 1 }),
{}
);
}
function containsDistinct(A, B) {
let distrA = getDistribution(A);
let distrB = getDistribution(B);
return Object.entries(distrA).every(([k, v]) => distrB[k] && distrB[k] >= v);
}
console.log("a in b = ", containsDistinct(a, b));
console.log("a in c = ", containsDistinct(a, c));
The output is:
a in b = true
a in c = false