Get the unique value from 3 or more arrays [duplicate] - javascript

This question already has answers here:
Completely removing duplicate items from an array
(11 answers)
Closed 1 year ago.
In this case I have 3 arrays in javascript:
var array1 = ['124','10','100','190','1000'];
var array2 = ['124','100','190', '45'];
var array3 = ['124','100','175','19','1900'];
I need a script that get the unique values from 3 or more arrays (in this case 3 arrays). the result should be:
['10','1000','45','175','19','1900']
Thanks for the help

You could take a Map and set known keys to value false and vice versa.
Then map the map, filter and map only the keys.
In pieces:
Make a single array with all values from the arrays with spread syntax ....
Reduce the array wih a Map and set unseen values to true and seen values to false. The result ia a map with all values as key and as value either true or false, depending on uniqueness or not.
By having a map, you need to take only the keys with a value true. This requires an array from the map.
Filter the array to get only unique keys.
Map the array to get only the key.
The result is an array with unique values.
const
a = ['124', '10', '100', '190', '1000'],
b = ['124', '100', '190', '45'],
c = ['124', '100', '175', '19', '1900'],
unique = Array
.from([...a, ...b, ...c].reduce((m, v) => m.set(v, !m.has(v)), new Map))
.filter(([, b]) => b)
.map(([v]) => v);
console.log(unique);

This is quite elegant solution to this problem. It looks for global unique values even in the same array.
var array1 = ['124','10','100','190','1000'];
var array2 = ['124','100','190', '45'];
var array3 = ['124','100','175','19','1900'];
function getUniqueValues(...arrays) {
const concatetedArray = arrays.flat();
return arrays.reduce((accumulator, current) => {
return [...accumulator, ...current.filter((currentItem) => concatetedArray.indexOf(currentItem) === concatetedArray.lastIndexOf(currentItem))];
}, [])
}
console.log(getUniqueValues(array1, array2, array3));

A solution is to use an object like this:
var array1 = ['124', '10', '100', '190', '1000'];
var array2 = ['124', '100', '190', '45'];
var array3 = ['124', '100', '175', '19', '1900'];
const obj = {};
for (let i = 0; i < array1.length; i++) {
if (!obj[array1[i]]) {
obj[array1[i]] = 0;
}
obj[array1[i]]++;
}
for (let i = 0; i < array2.length; i++) {
if (!obj[array2[i]]) {
obj[array2[i]] = 0;
}
obj[array2[i]]++;
}
for (let i = 0; i < array3.length; i++) {
if (!obj[array3[i]]) {
obj[array3[i]] = 0;
}
obj[array3[i]]++;
}
const uniques = [];
Object.keys(obj).forEach(key => {
if (obj[key] == 1) {
uniques.push(key);
}
})
console.log(uniques);

Related

Converting an array of arrays into an object with key and value with javascript [duplicate]

This question already has answers here:
How to convert an array of key-value tuples into an object
(14 answers)
Closed 1 year ago.
method input: (['name', 'marcus'], ['address', 'New York']
method output: {name: marcus, address: New York}
How do i do it?
cont array = [['c','2'],['d','4']];
function objectify()
{
array.forEach(arrayElement => { for(let i = 0; i<2; i++){
const obj = Object.assign({array[i][i]}, array[i++])
}
return obj;
})
}
console.log(objectify);
You can use Object.fromEntries()
const data = [['name', 'marcus'], ['address', 'New York']];
const result = Object.fromEntries(data);
console.log(result);
1) If you are using forEach then you don't have to use for loop inside it
array.forEach(arrayElement => { for(let i = 0; i<2; i++){
const obj = Object.assign({array[i][i]}, array[i++])
}
2) You shouldn't hardcode the length upto which i will run, because it can be of any length.
for(let i = 0; i<2; i++)
If you are using forEach then you should loop over the array and get the key and value and set it into the resultant object.
function objectify(array) {
const result = {};
array.forEach((o) => {
const [key, value] = o;
result[key] = value;
});
return result;
}
const array = [
["c", "2"],
["d", "4"],
];
console.log(objectify(array));

comparing array of objects and assigning similarity score

I am attempting to compare two array of object and assigning them a similarity score based of common items in the array.
I was able to compare the arrays but I am running into issue with using the same concept on array of objects.
let array1 = [{key1:['item1','item2','item3','item4']},{key2:['event3','event4']}];
let array2 = [{key1:['item1','item4','item2','item8']},{key2:['event4','event2']}];
let arrayA=['item1','item2','item3','item4'];
let arrayB=['item1','item4','item2','item8'];
function SimilarityPercentage(arrayA,arrayB){
let answer =arrayA.filter(function(item) {
return arrayB.indexOf(item) >= 0;
}).length
return answer/(Math.max(arrayA.length,arrayB.length))*100
}
console.log(SimilarityPercentage(arrayA,arrayB));// 75
Given array1 and array2 , I would like the result split out a similarity score, similar to the function above. I would like to use the rand index calculation : https://en.wikipedia.org/wiki/Rand_index#targetText=The%20Rand%20index%20or%20Rand,is%20the%20adjusted%20Rand%20index.
You could get the values and calculate the common score.
function similarityPercentage(arrayA, arrayB) {
return 100 * arrayA.filter(Set.prototype.has, new Set(arrayB)).length / Math.max(arrayA.length, arrayB.length);
}
function similarities(a, b) {
var parts = a.map((o, i) => similarityPercentage(Object.values(o)[0], Object.values(b[i])[0]));
return parts.reduce((a, b) => a + b, 0) / parts.length;
}
var array1 = [{ key1: ['item1', 'item2', 'item3', 'item4'] }, { key2: ['event3', 'event4'] }],
array2 = [{ key1: ['item1', 'item4', 'item2', 'item8'] }, { key2: ['event4', 'event2'] }],
arrayA = ['item1', 'item2', 'item3', 'item4'],
arrayB = ['item1', 'item4', 'item2', 'item8'];
console.log(similarityPercentage(arrayA, arrayB)); // 75
console.log(similarities(array1, array2)); // 62.5
You could do something like this:
var array1 = [val1,val2,val3];
var array2 = [val1,val4,val5];
var sim = [];
var simscore = 9;
if (array1.length > array2.length) {
for (var i = 0; i < array1.length; i++) {
if(array1[i] == array2[i]) {
sim.push(i);
simarr = array1;
simscore ++;
}
}
}else{
for (var i = 0; i < array2.length; i++) {
if(array1[i] == array2[i]) {
sim.push(i);
simarr = array2;
simscore ++;
}
}
}
console.log(sim);
console.log("Percent similar: ", simscore/simarr.length);
This will add the similar index to an array sim and increase the count of similar indexes by 1, always for the longer array, then print the percent of similarity.
First of all, your sample arrays are not well-structured, and your problem can be done more quickly if you restructure them.
Since you have not provided a formula for calculating the similarity between array1 and array2, I assume that every each of these arrays has equal length, and every item in them represents an object which has only one property (with the same name), and that property itself is an array. One obvious approach is to calculate every similarity score of the related child arrays of these two arrays to be calculated and then calculate the total similarity by averaging every key's similarity score.
Assumptions:
array1 and array2 have equal length
The nth element of array1 has only one property with the name keyFoo and the nth element of array2 also has only one property with the name keyFoo and keyFoo property of these two arrays are arrays themselves and must be compared to each other.
This quickly can be done using already provided SimilarityPercentage function:
function SimilarityPercentage2 (array1, array2) {
let similaritySum = 0;
for (let i = 0; i < array1.length; i++) {
const elem = array1[i];
const key = Object.keys(elem)[0];
similaritySum += SimilarityPercentage(elem[key], array2[i][key]);
}
return similaritySum / array1.length;
}
console.log(SimilarityPercentage2(array1, array2));
// output: 62.5

Check whether elements from one array are present in another array

What is the best way to check whether elements from one array are present in another array using JavaScript?
I come up with two of the following methods (but neither of them do I like very much).
Method1
for(let i = 0; i < arr1.length; ++i) {
for(let j = 0; j < arr2.length; ++j) {
if(arr1[i] === arr2[j]) {
arr1[i].isPresentInArr2 = true;
break;
}
}
}
Method2
const idToObj = {};
for(let i = 0; i < arr2.length; ++i) {
nameToObj[arr2[i].Id] = arr2[i];
}
for(let i = 0; i < arr1.length; ++i) {
if(nameToObj[arr1[i].Id]) {
nameToObj[arr1[i].Id].isPresentInArr2 = true;
}
}
Here I am assuming that I have two arrays of objects: arr1 and arr2. Those objects have a unique Id property each. And I am to check whether every object in arr1 is present in arr2.
I suppose the second method would be more efficient. Hope for interesting suggestions.
in terms of Algorithm Complexity wise , It's like trade-offs .
First One - Space time Complexity - 0, Run time complexity - 0(n2)
Second One - Space time Complexity - o(n), Run time complexity - 0(n)
If it's performance focussed , go for second one .
In terms of js way , you have many ways . Read about includes() and indexOf() inbuilt method in javascript to avoid writing a loop . Also make use of javascript map function . You could also uses underscore.js
Ref Check if an array contains any element of another array in JavaScript for more details .
You could sort the arrays, then check if they are equal to one another:
var array1 = [4, 304, 2032], // Some random array
array2 = [4, 2032, 304];
function areEqual(array1, array2) {
if (array1.sort().toString() == array2.sort().toString()) {
// They're equal!
document.getElementById("isEqual").innerHTML = ("Arrays are equal");
return true;
} else {
// They're not equal.
document.getElementById("isEqual").innerHTML = ("Arrays aren't equal");
return false;
}
}
areEqual(array1, array2);
<!DOCTYPE html>
<html>
<body>
<p id="isEqual"></p>
</body>
</html>
You could get a list of Ids, then sort the id's and compare the two array lists of Ids using JSON.stringify
// Test arrays to work with
const array1 = [{Id:10},{Id:11},{Id:13},{Id:12}]
const array2 = [{Id:10},{Id:11},{Id:12},{Id:13}]
const array3 = [{Id:10},{Id:11},{Id:12}]
function test(arr1, arr2) {
// Map of each array [0, 1, 2, etc...]
let map1 = arr1.map(i => i.Id)
let map2 = arr2.map(i => i.Id)
// Sort each array from lowest to highest
// Note: Some kind of sort is required if we are going to compare JSON values
map1.sort()
map2.sort()
// Test the mapped arrays against each other
return JSON.stringify(map1) === JSON.stringify(map2)
}
console.log(test(array1, array2))
console.log(test(array1, array3))
map over the arrays of objects to produce arrays of ids, then use every and includes to check the elements in one array against the elements of the other: ids1.every(el => ids2.includes(el)).
Here's a working example:
const arr1 = [{ id: 0 }, { id: 1 }, { id: 2 }];
const arr2 = [{ id: 0 }, { id: 1 }, { id: 2 }];
const arr3 = [{ id: 14 }, { id: 1 }, { id: 2 }];
const getIds = (arr) => arr.map(el => el.id)
function check(arr1, arr2) {
const ids1 = getIds(arr1);
const ids2 = getIds(arr2);
return ids1.every(el => ids2.includes(el));
}
console.log(check(arr1, arr2));
console.log(check(arr1, arr3));

push more than one elements at same index in array

how to push more than one element at one index of a array in javascript?
like i have
arr1["2018-05-20","2018-05-21"];
arr2[5,4];
i want resulted 4th array to be like:
arr4[["2018-05-20",5],["2018-05-21",4]];
tried pushing like this:
arr1.push("2018-05-20","2018-05-21");
arr1.push(5,4);
and then finally as:
arr4.push(arr1);
But the result is not as expected. Please someone help.
Actually i want to use this in zingChart as :
Options Data
Create an options object, and add a values array of arrays.
Calendar Values
In each array, provide the calendar dates with corresponding number values in the following format.
options: {
values: [
['YYYY-MM-DD', val1],
['YYYY-MM-DD', val2],
...,
['YYYY-MM-DD', valN]
]
}
Your question is not correct at all, since you cannot push more than one element at the same index of an array. Your result is a multidimensional array:
[["2018-05-20",5],["2018-05-21",4]]
You have to create a multidimensional array collecting all your data (arrAll)
Then you create another multidimensional array (arrNew) re-arranging previous data
Try the following:
// Your Arrays
var arr1 = ["2018-05-20","2018-05-21"];
var arr2 = [5, 4];
//var arr3 = [100, 20];
var arrAll = [arr1, arr2];
//var arrAll = [arr1, arr2, arr3];
// New Array definition
var arrNew = new Array;
for (var j = 0; j < arr1.length; j++) {
var arrTemp = new Array
for (var i = 0; i < arrAll.length; i++) {
arrTemp[i] = arrAll[i][j];
if (i === arrAll.length - 1) {
arrNew.push(arrTemp)
}
}
}
//New Array
Logger.log(arrNew)
Assuming the you want a multidimensional array, you can put all the input variables into an array. Use reduce and forEach to group the array based on index.
let arr1 = ["2018-05-20","2018-05-21"];
let arr2 = [5,4];
let arr4 = [arr1, arr2].reduce((c, v) => {
v.forEach((o, i) => {
c[i] = c[i] || [];
c[i].push(o);
});
return c;
}, []);
console.log(arr4);

Check if arrays contain shared elements regardless of index

I'd like to check if two arrays share elements regardless of order.
Given
array A: ['hello', 'how', 'are', 'you']
array B: ['how', 'are', 'hello']
Will return matches for 'hello', 'how', and 'are'
There seems to be something for PHP, array_intersect() (Check if array contains elements having elements of another array), but nothing for JavaScript.
I would use in if the values were in an object, but they are not:
if (key in obj) {
}
I could also do array.sort() to both arrays, but it's not guaranteed that both arrays will have same number of values. Therefore even if they are sorted, the compared indices would be off anyway.
How can I do this in JavaScript?
You can use filter to check if the same element is present in the other array.
var arr1 = ['hello', 'how', 'are', 'you'];
var arr2 = ['how', 'are', 'hello'];
var commonElements = arr1.filter(function(e) {
return arr2.indexOf(e) > -1;
});
console.log(commonElements);
You can also define this function on Array prototype
Array.prototype.intersection = function(arr) {
return this.filter(function(e) {
return arr.indexOf(e) > -1;
});
};
var arr1 = ['hello', 'how', 'are', 'you'],
arr2 = ['how', 'are', 'hello'];
var commonElements = arr1.intersection(arr2);
console.log(commonElements);
Considering performance I'd convert one of the array to an object, and then check intersection by traversing the other.
var arr1 = ['hello', 'how', 'are', 'you'];
var arr2 = ['how', 'are', 'hello'];
var set = {};
var intersect = [];
for (var i = 0; i < arr1.length; i++)
set[arr1[i]] = true;
for (var i = 0; i < arr2.length; i++)
if (set[arr2[i]]) intersect.push(arr2[i]);
But this method will ignore duplicate items in the arrays. And this may seem verbose compared to the filter and find solution. This may be helpful if you're doing intersection of large arrays.
In this approach, the first array is converted into a map, for fast lookup.
The second array is matched against the first.
The complexity is O(a) + O(b).
Pro: Elegance.
Con: Matching is continued after the overlap is detected.
function array_overlap(a, b) {
const lookup = a.reduce((m, n) => (m[n]=true, m), {});
const status = b.reduce((m, n) => (lookup[n] || m), false);
return status;
}
In ES6 syntax:
var intersection = arr1.filter( e => arr2.includes( e ) )

Categories

Resources