compare arrays using .some() - javascript

so i am trying to compare 2 arrays to see if their contents are the same, see example below
var array1 = [0,2,2,2,1]
var array2 = [0,2,2,2,3]
i want to compare those 2 arrays using the some method
so i will write a function that returns true if some of the numbers are in both arrays.
i have used the method perfectly fine on one array trying to find a particular value
function testArray(){
var bool = array1.some(function(value){
return value ===1;
});
}
console.log(bool)
but how to use it for 2 arrays? any help is appreciated

A solution with Array.prototype.every()
The every() method tests whether all elements in the array pass the test implemented by the provided function.
and Array.prototype.some()
The some() method tests whether some element in the array passes the test implemented by the provided function.
for the same task. Please watch the bangs!
var array1 = [0, 2, 2, 2, 1],
array2 = [0, 2, 2, 2, 3];
function compareEvery(a1, a2) {
if (a1.length !== a2.length) { return false; }
return a1.every(function (a, i) {
return a === a2[i];
});
}
function compareSome(a1, a2) {
if (a1.length !== a2.length) { return false; }
return !a1.some(function (a, i) {
return a !== a2[i];
});
}
document.write(compareEvery(array1, array2) + '<br>');
document.write(compareEvery(array1, array1) + '<br>');
document.write(compareSome(array1, array2) + '<br>');
document.write(compareSome(array1, array1) + '<br>');

You could use this approach
function compare(arr1, arr2) {
if (arr1.length != arr2.length) return false;
for (var i = 0; i < arr2.length; i++) {
if (arr1[i].compare) {
if (!arr1[i].compare(arr2[i])) return false;
}
if (arr1[i] !== arr2[i]) return false;
}
return true;
}
var array1 = [0, 2, 2, 2, 1];
var array2 = [0, 2, 2, 2, 3];
compare(array1, array2);

If you want to test if two arrays contains the same value, you can use some in combination with indexOf:
function containsSameValue(arr1, arr2) {
return arr1.some(function(value) {
return arr2.indexOf(value) > -1;
});
}
var array1 = [0, 2, 2, 2, 1];
var array2 = [0, 2, 2, 2, 3];
containsSameValue(array1, array2); // true
containsSameValue([1, 2, 3], [4, 5, 6]); // false

Related

How to check if two int arrays are permutations in JavaScript

How can I check if two integers arrays are permutations? I need to do it in JavaScript.
For example, I have two arrays:
a = [1, 2, 3, 4, 5]
and
b = [2, 3, 5, 1, 4]
I need the program to return true.
You could use a Map to store the occurrence count and then decrease that count whenever you find a mapping occurrence in the other array:
function isPermutation(a, b) {
if (a.length !== b.length) return false;
let map = new Map(a.map(x => [x, { count: 0 }]));
a.forEach(x => map.get(x).count++);
return b.every(x => {
let match = map.get(x);
return match && match.count--;
});
}
let a =[1,2,3,4,5,1];
let b = [2,3,1,5,1,4];
console.log(isPermutation(a, b));
The lazy solution:
let a = [1,2,3,4,5],
b = [2,3,5,1,4];
let res = JSON.stringify(a.sort()) === JSON.stringify(b.sort())
console.log(res)
The more efficient solution:
function perm (a,b) {
let map = a.reduce((acc,c) => {acc[c] = (acc[c] || 0) + 1; return acc},{})
for (el of b) {
if (!map[el] || map[el] == 0) {
return false;
} else {
map[el]--;
}
}
for (k in map) {
if (map[k] != 0) {
return false;
}
}
return true;
}
console.log(perm([1, 2, 3, 4, 5],[2, 3, 5, 1, 4])) // => true
console.log(perm([1, 2, 3, 4, 5, 5, 5],[2, 3, 5, 1, 4])) // => false
console.log(perm([1,1,2],[1,2,2])) // => false
console.log(perm([1,2,3,4,5,1],[2,3,1,5,1,4])) // => true
This solution is in hindsight similar to the one of #trincot but I guess slightly different enough to keep it posted.
The idea is the following: We create a map from the first array via reduce where the value is a count of occurrences. We then take the other array and subtract occurrences from the respective keys of map. If the key doesn't exist is or the value is already zero, we know this is not a permutation. Afterwords we loop the map, checking whether all values are exactly zero.
var a = [1, 2, 3, 4, 5];
var b = [2, 3, 5, 1, 4];
return a.filter(x => !b.includes(x)).length === 0
This will return true if all of the values in a exists in b, regardless of position.
This worked:
var a =[1,2,3,4,5,1];
var b = [2,3,1,5,1,4];
console.log(a.sort().toString() === b.sort().toString())

include() method for nested arrays

I am struggling with checking an array for an array within. It doesn't seem that the include() method is designed for it because it always returns false in this case. Below is example of an identical scenario with indexOf. Maybe all I need is syntax help, any ideas are most welcome.
arr = [1,[9,9],3,4,5];
if (arr.indexOf(el) !== -1) {
console.log(`the array contains ${el}`);
} else {
console.log(`doesn't contain ${el}`);
}
Of course the above returns true for 1, 3, 4, 5 and false for 2. And now the problem. I am trying to feed this method with an array like [9,9] to see if there's one already.
let el = [9,9];
// console: "doesn't contain 9,9"
On the other hand the below is okay which makes me think it's just a syntax issue(?)
let el = arr[1];
// console: "the array contains 9,9"
I found a way around it by writing a checker function with for loop but this quickly becomes bulky as you add requirements. I would love to know a smarter way.
Thank you.
The problem you have is that arrays are reference types. Because of this, comparing two arrays will return true only if the two arrays refer to the same underlying array, and will return false for different arrays, even if they hold the same values.
const arr1 = [1, 2];
const arr2 = [1, 2];
const arr3 = arr1;
console.log(arr1 === arr3);
console.log(arr1 !== arr2);
To fix your problem, your include function needs to compare by value (deep comparison), you can do this simply using JSON.stringify().
This method is fast but limited, it works when you have simple JSON-style objects without methods and DOM nodes inside
See this SO post about object comparison in JavaScript.
Here is a working example:
function include(arr, value) {
const stringifiedValue = JSON.stringify(value);
for (const val of arr) {
if (JSON.stringify(val) === stringifiedValue) {
return true;
}
}
return false;
}
console.log(include([1, 2, 3, 4], 3));
console.log(include([1, 2, 3, [1, 2]], [1, 2]));
console.log(include([1, 2, 3, [1, 2]], [1, 2, 3]));
Here is another way to do this deep comparison without JSON.stringify(), it works for inner arrays, and scalar values:
function include(arr, value) {
const valArity = Array.isArray(value) ? value.length : 1;
for (let item of arr) {
if (valArity > 1 && Array.isArray(item) && item.length === valArity) {
if (item.every((val, i) => val === value[i])) {
return true;
}
} else if (item === value) {
return true;
}
}
return false;
}
console.log(include([1, 2, 3, 4], 3));
console.log(include([1, 2, 3, [1, 2]], [1, 2]));
console.log(include([1, 2, 3, [1, 2]], [1, 2, 3]));
console.log(include([1, 2, 'abc', 4], 'abc'));
And here is a modified version that works for simple objects with scalar properties, arrays and scalars:
function include(arr, value) {
const valArity = Array.isArray(value) ? value.length : 1;
const isObject = value instanceof Object;
for (let item of arr) {
if (valArity > 1 && Array.isArray(item) && item.length === valArity) {
if (item.every((val, i) => val === value[i])) {
return true;
}
} else if (isObject && item instanceof Object && item) {
const numEntries = Object.keys(value).length;
const entries = Object.entries(item);
if (numEntries === entries.length) {
if (entries.every(([k, v]) => value[k] === v)) {
return true;
}
}
} else if (item === value) {
return true;
}
}
return false;
}
console.log(include([1, 2, 3, 4], 3));
console.log(include([1, 2, 3, [1, 2]], [1, 2]));
console.log(include([1, 2, 3, [1, 2]], [1, 2, 3]));
console.log(include([1, 2, { a: 1 }, 4], { a: 1 }));
console.log(include([1, 2, { a: 1, b: 2 }, 4], { a: 1 }));
console.log(include([1, 2, 'abc', 4], 'abc'));
Here we can do this using Array.prototype.some()
Notice we added a helper method to check each element, I did not bother writing object checking, but you get the idea.
Tweaked to support sub-arrays
let arr = [1, [9, 9], 3, 4, 5];
let el = [9, 9];
let arr2 = [1, [1,[9, 9]], 3, 4, 5];
let el2 = [1,[9, 9]];
const someCheck = (item, compare) => {
if(typeof item !== typeof compare) return false;
if(typeof item === 'string') return item === compare;
if(typeof item === 'number') return item === compare;
if(Array.isArray(item)) {
console.log('checking array');
return item.reduce((accum, o, i) => accum && (someCheck(o,compare[i])));
}
// no plain object support yet.
return false;
}
if (arr.some(e => someCheck(e, el))) {
console.log(`the array contains ${el}`);
} else {
console.log(`doesn't contain ${el}`);
}
if (arr2.some(e => someCheck(e, el2))) {
console.log(`the array contains ${el2}`);
} else {
console.log(`doesn't contain ${el2}`);
}
You need to loop through the array and check if each element is an array, then you check each index. Something like this:
let arr = [1,[9,9],3,4,5];
let el = [9,9];
let contains = true;
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
var equals = true
if(arr[i].length !== el.length)
equals = false;
for(var j = arr[i].length; j--;) {
if(arr[i][j] !== el[j])
equals = false;
}
if (equals) {
contains = true;
break;
}
} else {
if (arr.indexOf(el) !== -1){
contains = true;
break;
}
else{contains = false;}
}
}
if (contains) {
console.log(`the array contains ${el}`);
} else {
console.log(`doesn't contain ${el}`)
}

Error using Javascript filter() function in freecodecamp

function destroyer(arr) {
var arry=[];
for(var i=1;i<arr.length;i++)
{
arr[0] = arr[0].filter(cc => cc != arr[i]);
}
return arry;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
I basically have to return all the elements of the first sub-array which arent present in the rest of array.
Its displaying "arr[0].filter isnt a function.
destroyer([1, 2, 3, 1, 2, 3], 2, 3) should return [1, 1].
I basically have to return all the elements of the first sub-array which arent present in the array.
You aren't doing anything with the other arguments provided to the destroyer function - you have to test those arguments against arr, you shouldn't be testing arr against itself.
function destroyer() {
const [arr, ...excludeArr] = arguments;
return arr.filter(elm => !excludeArr.includes(elm));
}
console.log(
destroyer([1, 2, 3, 1, 2, 3], 2, 3)
);
function destroyer(arr, x, y) {
return arr.filter(item => (item != x) && (item != y))
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3))
const destroyer = (arr, ...args) => {
return arr.filter(item => args.indexOf(item) < 0);
};
const result = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
console.log(result);
as you said you should filter first subarray but you are sending only 1 array with int values and other values as argument, the actual usage of this function should be
function destroyer(arr) {
for(var i = 1; i < arr.length; i++)
{
arr[0] = arr[0].filter(cc => cc != arr[i]);
}
return arr[0];
}
destroyer([[1, 2, 3, 1, 2, 3], 2, 3]);
You forgot to call your method using the array. you have to surround it with another pair of [].
You can simply return the filtered arr[0] to get what you want.
function destroyer(arr) {
for (var i = 1; i < arr.length; i++) {
arr[0] = arr[0].filter(cc => cc != arr[i]);
}
return arr[0];
}
console.log(destroyer([[1, 2, 3, 1, 2, 3], 2, 3]));

JavaScript - filter through an array with arguments using for loop

I am trying to use the filter method on an array to loop through the array based on a variable number of arguments.
Below is my attempt at this:
function destroyer(arr) {
var argArr = arr.slice.call(arguments, 1);
var filteredArray = arr.filter(function(val) {
for (var i = 0; i < argArr.length; i++) {
return val != argArr[i];
};
});
console.log(filteredArray);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
When I do this, only the first element of the arguments array is disposed of. This therefore returns:
[1, 3, 1, 3]
I have found a few examples online of possible ways to resolve this but they are vastly different from what I understand just yet. Is there any way to get mine to work, or even understand why the additional elements of the arguments array are not being called.
If you use ES6 you can do it with rest operator and Array#includes function
function destroyer(arr, ...params){
return arr.filter(item => !params.includes(item));
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
With your logic you can do like this. If val is equal to the current argArr's item then return false, if nothing was found after the loop: return true
function destroyer(arr) {
var argArr = Array.prototype.slice.call(arguments, 1);
var filteredArray = arr.filter(function(val) {
for (var i = 0; i < argArr.length; i++) {
if(val === argArr[i]){
return false;
}
};
return true;
});
console.log(filteredArray);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Because with your code you always test if current element in filter is equal or not equal to second parameter in function which is 2 and return true/false. Instead you can use indexOf to test if current element in filter is inside arguments array.
function destroyer(arr) {
var argArr = arr.slice.call(arguments, 1);
var filteredArray = arr.filter(function(val) {
return argArr.indexOf(val) == -1
});
console.log(filteredArray);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Problem is in your this line
return val != argArr[i];
Change logic like this , it will avoid to do extra looping also .
function destroyer(arr) {
var argArr = arr.slice.call(arguments, 1); debugger
var filteredArray = arr.filter(function(val) {
return !(argArr.indexOf(val) >= 0);
});
console.log(filteredArray);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

Remove elements from array using javascript filter

I have two arrays and want to remove duplicates using filter function.
Here is my code:
arr1 = [1, 2, 3, 1, 2, 3];
arr2 = [2, 3];
result = [1, 1];
var result = arr1.filter(function(value, index) {
for (var i = 0; i <= arr2.length; i++) {
if (value !== arr2[i]) {
return value === arr2[i];
}
}
}
Thanks in advance! Any help would be great!
You can try to convert arguments into array and then check if the value from the initial array is in arguments array:
function destroyer(arr) {
// Converting arguments into array
var args = Array.prototype.slice.call(arguments);
arr = arr.filter(function (val) {
return args.includes(val)===false;
});
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3); // returns[1,1]
First of all, if its not a problem adding a library. I am using uniq from underscore.js.
uniq_.uniq(array, [isSorted], [iteratee]) Alias: unique
Produces a duplicate-free version of the array, using === to test object
equality. In particular only the first occurence of each value is
kept. If you know in advance that the array is sorted, passing true
for isSorted will run a much faster algorithm. If you want to compute
unique items based on a transformation, pass an iteratee function.
_.uniq([1, 2, 1, 4, 1, 3]);
=> [1, 2, 4, 3]
Other solution is using pure JS:
var newArray = [1, 2, 2, 3, 3, 4, 5, 6];
var unique = newArray.filter(function(itm, i, a) {
return i == newArray.indexOf(itm);
});
alert(unique);
But first you will need to combine your arrays in a new array:
var newArray = arr1.concat(arr2);
JS Fiddle
I hope this helped! :)
Here's one way without the filter function:
var arr1 = [1, 2, 3, 1, 2, 3];
var newArr = [];
for(var i = 0;i < arr1.length;i++){
if (newArr.indexOf(arr1[i]) === -1) {
newArr.push(arr1[i]);
}
}
Just use Array.prototype.filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
with Array.prototype.indexOf()
The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
var arr1 = [1, 2, 3, 1, 2, 3],
arr2 = [2, 3],
result = arr1.filter(function (a) {
return !~arr2.indexOf(a);
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
As in this JS Fiddle, using filter()
arr1 = [1, 2, 3, 1, 2, 3];
arr2 = [2, 3];
result = [1, 1];
var result = arr1.filter(myFunc);
function myFunc(value) {
for (var i = 0; i < arr2.length; ++i) {
// to remove every occurrence of the matched value
for (var j = arr1.length; j--;) {
if (arr1[j] === arr2[i]) {
// remove the element
arr1.splice(j, 1);
}
}
}
}
document.getElementById('result').innerHTML = arr1;
console.log(arr1);
// Output: [1,1]
<div id="result"></div>

Categories

Resources