I have two javascript array and I need to compare them. For example, suppose I have these two arrays:
var array1 = ["1", "2", "3", "4"];
var array2 = ["4", "1", "3", "2"];
These arrays are equal in fact and I want to get true as a result of comparison. What is the best and fastest way for doing that?
What you really have are two sets, not arrays, but unfortunately JavaScript does not provide any sort of "set" datatype. The easiest way to do this type of check is by using some sort of functional JavaScript library, such as lodash.
Using lodash's _.union function makes this trivially easy.
function setsEqual(a, b) {
var u = _.union(a, b);
return u.length === a.length && u.length === b.length;
}
If you want to do this without external libraries, you can do so using Array.prototype.every.
function setsEqual(a, b) {
return a.length === b.length
&& a.every(function (v) { return b.indexOf(v) !== -1; });
}
The best way and fastest way to do this is using object which keep tracks the value of and its count. Then we can see if it exist in second array. Try this
function compare(arr1, arr2){
var obj={}, len = arr1.length, i=0, isSame=true, prop;
if(arr1.length === arr2.length){
for(;i<len;i++){
if(obj[arr1[i]]){
obj[arr1[i]] = obj[arr1[i]]+1;
} else{
obj[arr1[i]] =1;
}
}
i=0, len = arr2.length;
for(;i<len;i++){
if(obj[arr2[i]]){
obj[arr2[i]] = obj[arr2[i]]-1;
} else{
isSame = false;
break;
}
}
for (prop in obj){
if(obj[prop] > 0){
isSame = false;
break;
}
}
}else{
isSame = false;
}
return isSame;
}
Try removing matching elements until both elements are empty:
var array1 = ["1", "2", "3", "4", "1", "5"];
var array2 = ["1", "5", "2", "3", "4", "1"];
var isSame = false;
if(array1.length != array2.length)
isSame = false;
else
{
for(var i = 0; i < array1.length; i ++)
{
var removed = false;
for(var j = 0; j < array2.length; j ++)
{
if(array2[j] == array1[i])
{
// remove from array2
array1.splice(i, 1);
// remove from array1
array2.splice(j, 1);
// go back 1 for i
removed = true;
i --;
break;
}
}
if(!removed)
break;
}
if(array1.length == 0 && array2.length == 0)
isSame = true;
}
I don't suppose that is a fastest approach but it can be useful for a little arrays with primitives
function compareArrays(a, b) {
var copyA = a.slice(),
copyB = b.slice();
if (a.length !== b.length) { return false; }
return copyA.sort().toString() === copyB.sort().toString();
}
Return status from function after comparing two array.
arr1 = [101,12,13,10,4];
arr2 = [101,4,12,13,10];
function compareTwoArray(arr1, arr2) {
return arr1.length === arr2.length &&
arr1.sort().every((val, index)=> val === arr2.sort()[index]);
}
console.log(compareTwoArray(arr1, arr2))
Related
Doing the DNA challenge and so close but clearly misunderstanding prototype.split(""). What's the best way to turn these strings ["AC", "CA", "TA"] into subarrays? [["A","C"]["C","A"]["T","A"]]
function pairElement(str) {
//break into array
var arr = str.split("");
//add new letter (could be refactored as switch)
for (i = 0; i < arr.length; i++) {
if (arr[i] == "G") {
arr[i] += "C";
} else if (arr[i] == "C") {
arr[i] += "G";
} else if (arr[i] == "T") {
arr[i] += "A";
} else if (arr[i] == "A") {
arr[i] += "T";
}
}
//break into arrays again
//this is how I'm trying to use.split to break it up. Doesn't work.
var broken = [];
for (x = 0; x < arr.length; x++) {
broken += arr[x].split("");
}
//return
return arr;
}
console.log(pairElement("GCG"));
you can use .map and split them by ""
var o = ["AC", "CA", "TA"];
var s = o.map(e=> e.split(""));
console.log(s)
You actually have to just push the split result in the broken array and return it !
function pairElement(str) {
//break into array
var arr = str.split("");
//add new letter (could be refactored as switch)
for (i = 0; i < arr.length; i++) {
if (arr[i] == "G") {
arr[i] += "C";
} else if (arr[i] == "C") {
arr[i] += "G";
} else if (arr[i] == "T") {
arr[i] += "A";
} else if (arr[i] == "A") {
arr[i] += "T";
}
}
//break into arrays again
//this is how I'm trying to use.split to break it up. Doesn't work.
var broken = [];
for (x = 0; x < arr.length; x++) {
broken.push(arr[x].split(""));
}
//return
return broken;
}
console.log(pairElement("GCG"));
To answer your 'what's the best way' question, map your arrays into the split versions of themselves:
const subarrays = array.map(pair => pair.split());
Very simple in functional style:
> seq = ['AC', 'CA', 'TA']
[ 'AC', 'CA', 'TA' ]
> seq.map(s => s.split(''))
[ [ 'A', 'C' ], [ 'C', 'A' ], [ 'T', 'A' ] ]
Overall, I'd do some refactoring on the whole function:
var m = new Map([["G", "C"], ["C", "G"], ["A", "T"], ["T", "A"]]);
function pairElement(str) {
return [...str].map(c => [c, m.get(c)]);
}
console.log(pairElement("GCG"));
And if there's a guarantee that the sub-arrays are never mutated, then you can save a good bit of memory by reusing arrays instead of creating them over and over.
var m = new Map([["G", ["G", "C"]], ["C", ["C", "G"]], ["A", ["A", "T"]], ["T", ["T", "A"]]]);
function pairElement(str) {
return [...str].map(c => m.get(c));
}
console.log(pairElement("GCG"));
But to directly answer your question, you can do it without explicit .split() calls. Since you know there's always two characters, you can use parameter destructuring on the strings.
var arr = ["AC", "CA", "TA"];
var s = arr.map(([a, b]) => [a, b]);
console.log(s)
Or even a little shorter using rest syntax, like this:
var arr = ["AC", "CA", "TA"];
var s = arr.map(([...a]) => a);
console.log(s)
Or using spread syntax in an array literal:
var arr = ["AC", "CA", "TA"];
var s = arr.map(s => [...s]);
console.log(s)
I am searching for a function which compare how much values match in an array. It should be sequence dependent. That mean i.e. the first object in the first array should be compared to equality to the first object in the second array and so on. I actually looked at this, but there become only the length compared and the length is in my case always the same. The possibly objects in the array are 1,2,3,4,5,6,7,8,9. Should I split the arrays and compare them then and when yes how?
Here are two examples:
var array1 = ["3","4","2"];
var array2 = ["9","4","7"];
// result = 1
second example:
var array1 = ["9","4","7","3"];
var array2 = ["3","4","7","2"];
// result = 2
Try this
var array1 = ["3","4","2"];
var array2 = ["9","4","7"];
function equal(array1, array2) {
var len = array1.length, i, count = 0;
for (i = 0; i < len; i++) {
if (array1[i] === array2[i]) {
count++;
}
}
return count;
}
console.log(equal(array1, array2));
Solution which iterates over the items and count the equal elements.
function compare(a1, a2) {
var i = 0, count = 0;
while (i < a1.length && i < a2.length) {
a1[i] === a2[i] && count++;
i++;
}
return count;
}
document.write(compare(["3", "4", "2"], ["9", "4", "7"]) + '<br>');
document.write(compare(["9", "4", "7", "3"], ["3", "4", "7", "2"]) + '<br>');
I have an javascript array and I want to delete an element based on the value of the array, this is my array and this is what I have tried without success.
array = []
array.push (["Mozilla","Firefox",1.10])
index = array.indexOf(["Mozilla","Firefox",1.10])
array.splice(index, 1)
But it doesn't work, any idea¿?
You're trying to compare arrays, which are objects and have unique addresses. Your index variable is -1.
Try ['Mozilla','Firefox',1.10] === ['Mozilla','Firefox',1.10] in your console, you'll see that just because two arrays have the same values, it doesn't mean they are the same array.
What you need is a deep-equals style of comparison, that checks each value in the array, to see if two arrays have a likeness.
Take a look at lodash's isEqual function for an idea.
Here's a simple looping function:
function deepIndex(array, comparison) {
var i, j;
main:
for (i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
for (j = 0; j < array[i].length; j++) {
if (array[i][j] !== comparison[j]) {
continue main;
}
}
return i;
}
}
}
var arr = [];
arr.push('string', ['Mozilla','Firefox',1.10], 'thing');
var index = deepIndex(arr, ['Mozilla','Firefox',1.10])
console.log(index, arr);
arr.splice(index, 1);
console.log(arr);
Take a look at this:
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
This is function, made by the Creator of JQUery.
Basically you take the Index of one thing and than it is getting removed
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
//Equals Function taken from:
//http://stackoverflow.com/questions/7837456/comparing-two-arrays-in-javascript
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
array = [];
array.push (["Mozilla","Firefox",1.10]);
array.push (["Microsoft","Spartan",1.0]);
array.push (["Safari","Safari",1.4]);
index = indexOfArr(array,["Mozilla","Firefox",1.10]);
array.remove(index, index);
document.getElementById("length").innerHTML = array.length;
for(var i = 0; i < array.length; i++){
document.getElementById("elems").innerHTML += "<br>"+array[i];
}
function indexOfArr(hay, needle){
for(var i = 0; i < hay.length; i++){
if (hay[i].equals(needle)){
return i;
}
}
return -1;
}
<span id = "length"></span><br>
<span id = "elems">Elements:</span>
You can use the fiter metodh, instead of indexOf.
Within the callback of that method, you can choose different approaches:
Use toString on the arrays and compare the two strings
Test for the length and the content, by iterating over the contained elements
... Continue ...
In any case using === will solve the problem, unless the object contained is exactly the same against which you are trying to match.
By the same, I mean the same. We are non speaking about having the same content, but to be the same instance.
Loop over your array and check the equality:
array = [];
array.push(["Mozilla", "Firefox", 1.10]);
for (var i = 0; i < array.length; i++) {
if (arraysEqual(array[i], ["Mozilla", "Firefox", 1.10])) {
array.splice(i, 1);
}
}
function arraysEqual(a, b) {
if (a === b) return true;
if (a === null || b === null) return false;
if (a.length != b.length) return false;
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
JSFiddle: http://jsfiddle.net/ghorg12110/r67jts35/
Based on this question : How to check if two arrays are equal with JavaScript?
You can do something like this
array = []
array.push (["Mozilla","Firefox",1.10])
tempArray = array[0];
index = tempArray.indexOf("Mozilla","Firefox",1.10)
array.splice(index, 1)
You can build on this if you put for loop instead of hard coding.
I have a simple application in which I want compare two arrays.
function check() {
var Array1 = value.length;
var Array2 = selected_value.length;
alert(Array1 + "," + Array2);
for (var i = 0; i < Array1; i++) {
for (var j = 0; j < Array2; j++) {
if (value[i] == selected_value[j]) {
alert("both div are same");
}
}
}
}
my arrays have 4 elements each but the if condition is not satisfied.
try to view yout values. before if write console.log( value[i], selected_valuw[j]) and check whether they are alike
Here is function, with which you can compare two arrays
function arraysEqual(arr1, arr2) {
if(arr1.length !== arr2.length)
return false;
for(var i = arr1.length; i--;) {
if(arr1[i] !== arr2[i])
return false;
}
return true;
}
Source
You can check if array return false, like this
if(!arrayEqual(arr1,arr2)) {
// false
}
I need to search for the presence of an array inside an array. It is similar to jQuery.inArray function.
For
var a = [ [1,2], [1,3] ];
console.log( jQuery.inArray([1,3],a ) )
I get -1 as ans. How to do this?
Thank you
In V8 (that is, Chrome), there is a nifty trick: while == does not work for arrays, <= && >= does.
You can iterate and check for each item if it's appearent:
for(var i = 0; i < a.length; i++) {
if(a[i] >= [1, 3] && a[i] <= [1, 3]) alert(i);
}
For other browsers, you'd need a function that checks for array equality:
http://www.svendtofte.com/code/usefull_prototypes/prototypes.js
Array.prototype.compareArrays = function(arr) {
if (this.length != arr.length) return false;
for (var i = 0; i < arr.length; i++) {
if (this[i].compareArrays) { //likely nested array
if (!this[i].compareArrays(arr[i])) return false;
else continue;
}
if (this[i] != arr[i]) return false;
}
return true;
}
Then:
for(var i = 0; i < a.length; i++) {
if(a[i].compareArrays([1, 3])) alert(i);
}
function inArray (needle, haystack) {
for (var idx in haystack) {
if (haystack[idx].join(',') == needle.join(','))
return idx;
}
return -1;
}
try this
function look4arr(arr, v) {
for (var i = 0, l = arr.length; i < l; i += 1) {
if (arr[i].toString() === v.toString()) { //or use +''
return true;
}
}
return false;
}
var a = [[1,2], 2],
ok = [1,2],
ko = [2,3]
look4arr(a, ok); // true
look4arr(a, ko); // false
// as far as the array you are looking at contains primitives seem to work fine
if you need to search for something "more" ...I mean object literals, regexp, functions
You could use a function similar to the following one
function look4x(arr, v) {
for (var i = 0, isObjOrArray = false, l = arr.length; i < l; i += 1) {
isObjOrArray = {}.toString.call(arr[i]).match(/\[object\s(Array|Object)\]/);
if (
(isObjOrArray && JSON.stringify(arr[i])+'' == JSON.stringify(v)+'' )
||
(!isObjOrArray && arr[i].toString() === v.toString())
) {
return true;//or i if a jQuery.inArray output is needed
}
}
return false; // or -1 ... if ... jQuery.inArray
}
var a = [
[1,[1,[1,[1,2]]]],
2,
true,
'hei',
Infinity,
{"o" : "s", 'd':[1,2,3]},
new RegExp(/\s/),
function(){alert('hei');}
],
ok = [1,[1,[1,[1,2]]]];
alert(
look4x(a, [1,[1,[1,[1,2]]]])
&&
look4x(a, true)
&&
look4x(a, 'hei')
&&
look4x(a, Infinity)
&&
look4x(a, {"o" : "s", 'd':[1,2,3]})
&&
look4x(a, new RegExp(/\s/))
&&
look4x(a, function(){alert('hei');})
); // true, in this case
Please note that I didn`t tested it yet with a complete test; I'll post a test asap
Event if I seem to be late, hope it can help someone.
Bye