4

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 ?

Andy
63.6k13 gold badges72 silver badges99 bronze badges
asked Oct 27, 2019 at 15:40

3 Answers 3

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]));

answered Oct 27, 2019 at 15:53

Comments

1

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));

answered Oct 27, 2019 at 16:09

Comments

0

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

answered Oct 27, 2019 at 16:20

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.