compare 2d array with 1d array in javascript - javascript

var player1=["t1", "t9", "t7", "t8", "t2"];
var player2=["t5", "t3", "t4", "t6"];
var winmoves=[[t1,t2,t3],[t4,t5,t6],[t7,t8,t9],[t1,t4,t7],[t2,t5,t8],[t3,t6,t9],[t1,t5,t9],[t3,t5,t7]];
else if (moves>=3 && moves<=9) {
moves+=1;
if (turn==1) {
var i=0;
turn=2;
x.innerHTML="<img src='x.png'/>";
player1.push(x.id);
while(i<=moves){
if (winmoves[i] in player1) {
alert("player1 wins");
document.getElementById("player1").innerHTML=1;
}
i+=1;
}
}
i have 1d array player1 and 2d array winmoves in javascript and i want to check that w[0]'s all values are present in p and so on for w[1],w[2],etc.
if condition with (winmoves[i] in player1) is not working.
i don't know if i am writing this write.
help me guys i am stuck here how can i do so.
It is not working even after i have made these changes.
else if (moves>=3 && moves<9) {
moves+=1;
if (turn==1) {
var i=0;
turn=2;
x.innerHTML="<img src='x.png'/>";
player1.push(x.id);
while(i<=moves){
mapped1 = winmoves.map(a1 => a1.every(e1 => player1.includes(e1)));
if (mapped1[i]) {
alert("player1 wins");
document.getElementById("player1").innerHTML=1;
}
i+=1;
}
}
else if (turn==2) {
turn=1;
var i=0;
x.innerHTML="<img src='o.png'/>";
turn=1;
player2.push(x.id);
while(i<=moves)
{
mapped2 = winmoves.map(a => a.every(e => player2.includes(e)));
if (mapped2[i]) {
alert("player2 wins");
document.getElementById("player2").innerHTML=1;
}
i+=1;
}
}
}

I would simply do this with a simple invention of Array.prototype.intersect() and the rest is such a straightforward single liner.
Array.prototype.intersect = function(a) {
return this.filter(e => a.includes(e));
};
var player1 = ["t1","t2","t3","t5","t7"],
winmoves = [["t1","t2","t3"],["t4","t5","t6"],["t7","t8","t9"],["t1","t4","t7"],["t2","t5","t8"],["t3","t6","t9"],["t1","t5","t9"],["t3","t5","t7"]];
filtered = winmoves.filter(a => a.intersect(player1).length == a.length);
mapped = winmoves.map(a => a.intersect(player1).length == a.length);
console.log(filtered);
console.log(mapped);
OK we have a generic Array method which finds the intersection of two arrays. (inbetween the array it's called upon and the one provided as argument) It's basically a filter checking each item of first array to see whether it is included in the second array. So we filter out the items exist in both arrays.
To obtain the filtered array we utilize Array.prototype.filter() again. This time our first array is winmoves which includes arrays that we will check for each the intersection with player1 array. If the intersection length is equal to winmove's item's length that means all elements of winmove's item is existing in the player1 array. So we return that array item to the filtered.
Specific to your case without using an intersect method you can utilize Array.prototype.every() as follows;
var player1 = ["t1","t2","t3","t5","t7"],
winmoves = [["t1","t2","t3"],["t4","t5","t6"],["t7","t8","t9"],["t1","t4","t7"],["t2","t5","t8"],["t3","t6","t9"],["t1","t5","t9"],["t3","t5","t7"]];
filtered = winmoves.filter(a => a.every(e => player1.includes(e)));
mapped = winmoves.map(a => a.every(e => player1.includes(e)));
console.log(filtered);
console.log(mapped);

What you could do is use nested for loops
for(var j = 0, j < elemInP, j++){
int flag = 0;
for(var x = 0, x < elemInWx, x++){
for(var y = 0, y < elemInWy, y++){
if(p[j] == w[x][y]){
flag = 1;
/*There is no need to run this loop once the value has been found*/
break;
}
}
if(flag){
/*If we have found the value no need to keep looking*/
break;
}
}
if(!flag){
print p[j] is not in w;
}
}
This is just a general idea of one way to compare the two arrays. The actual syntax of the code will need to be edited to work in JavaScript as this is just basic pseudocode. Flag is just a variable that holds if the value was found or not and is reset for each new value. For efficiency, you could have a break/return after setting flag = 1, but this is

Related

Write a function getDuplicates

Write a function getDuplicates that returns an array of all the elements that appear more than once in the initial items array (keeping the order). If an element appears many times, it should still be added to the result once.
This is my code
function getDuplicates(items) {
let result = [];
if (items === [0,0,0,0]) {return [0]}
for (let i = 0; i < items.length; i++) {
for (let j = i + 1; j < items.length; j++) {
if (items[i] === items[j]) {
result.push(items[i])
}
}
}
return result
}
I get an error:
input: [0, 0, 0, 0]
Hide details
Expected:
[0]
Received:
[0,0,0,0,0,0]
In JavaScript, arrays are objects, so when you use the === operator to compare two arrays, it will only return true if they are the exact same object in memory.
Use a Set to track duplicates: Instead of using an array to store the duplicate elements, we can use a Set to make sure we don't add duplicates to the result array. A Set is an efficient data structure for checking if an element exists or not, and it also automatically removes duplicates.
Use a single loop: Instead of using two nested loops to compare every element with every other element, we can use a single loop to keep track of the elements we've seen so far, and add them to the result if we see them again.
function getDuplicates(items) {
const result = [];
const seen = new Set();
for (const item of items) {
if (seen.has(item) && !result.includes(item)) {
result.push(item);
} else {
seen.add(item);
}
}
return result;
}
console.log(getDuplicates([0, 1, 0, 1, 2]))
a modified version of yours
function getDuplicates(items) {
let result = [];
let added = {};
for (let i = 0; i < items.length; i++) {
if (!added[items[i]] && items.indexOf(items[i], i + 1) !== -1) {
result.push(items[i]);
added[items[i]] = true;
}
}
return result;
}
console.log(getDuplicates([0, 1, 0, 1, 2]))
or in short doing the same
const getDuplicates = items => items.filter((item, index) => items.indexOf(item) !== index && items.lastIndexOf(item) === index);
console.log(getDuplicates([0, 1, 0, 1, 2]))
The best way to filter out the unique elements in an array is JavaScript Set
You cannot compare two arrays just like array1 === array2 because, Arrays have the type Object and you cannot compare two object just with equal to operator. Objects are not compared based on their values but based on the references of the variables. So when you compare two arrays which have same values using array1 === array2, it will compare its memory location only, not its values. So it will be only false.
The best way to achieve your result is to create an Array by checking the number of occurrences of nodes in the parent array, having occurrences count more than one and use a Set to remove the repetitions
function getDuplicates(items) {
return Array.from(new Set(items.filter(node => items.filter(x => node === x).length > 1)))
}
console.log(getDuplicates([0, 1, 0, 1, 2]))
You can try it:
Check if the current number is duplicated by using filter to check the length of an array.
Check if the result array contains duplicates.
function getDuplicates(items) {
let result = [];
for (let i = 0; i < items.length; i++) {
if ((items.filter(item => item == items[i])).length > 1 && !result.includes(items[i])) {
result.push(items[i]);
}
}
return result;
}
console.log(getDuplicates([0, 0, 0, 0]));
So. first of all - comparing 2 array will not work, (Somebody already explained why above).
Your code doesn't work because of if statement. You're checking if an array doesn't have any value except 0.
Try summing all numbers in the array and check if it's 0.
if(arr.reduce((accum, curr) => return accum += curr) == 0) {
return [0];
}
Your code is close, but there are a few issues that need to be addressed. First, you should not use the strict equality operator === to compare arrays, because it checks whether the two arrays have the same reference, not the same elements. Instead, you can use the JSON.stringify() method to compare the string representations of the arrays.
Second, your code only returns [0] if the input array is [0,0,0,0], which is not a general solution for finding duplicates. You can use an object to keep track of the count of each element in the array, and then add the elements that have a count greater than 1 to the result array.
Here's the corrected code:
function getDuplicates(items) {
let result = [];
let count = {};
for (let i = 0; i < items.length; i++) {
if (count[items[i]] === undefined) {
count[items[i]] = 1;
} else {
count[items[i]]++;
}
}
for (let i = 0; i < items.length; i++) {
if (count[items[i]] > 1 && result.indexOf(items[i]) === -1) {
result.push(items[i]);
}
}
return result;
}
This code keeps track of the count of each element in the count object, and then adds the elements that have a count greater than 1 to the result array, while making sure not to add duplicates to the result.

Quickest way to check if 2 arrays contain same values in javascript

Is there a quicker or more efficient way to check that two arrays contain the same values in javascript?
Here is what I'm currently doing to check this. It works, but is lengthy.
var arraysAreDifferent = false;
for (var i = 0; i < array1.length; i++) {
if (!array2.includes(array1[i])) {
arraysAreDifferent = true;
}
}
for (var i = 0; i < array2.length; i++) {
if (!array1.includes(array2[i])) {
arraysAreDifferent = true;
}
}
To reduce computational complexity from O(n ^ 2) to O(n), use Sets instead - Set.has is O(1), but Array.includes is O(n).
Rather than a regular for loop's verbose manual iteration, use .every to check if every item in an array passes a test. Also check that both Set's sizes are the same - if that's done, then if one of the arrays is iterated over, there's no need to iterate over the other (other than for the construction of its Set):
const arr1Set = new Set(array1);
const arr2Set = new Set(array2);
const arraysAreDifferent = (
arr1Set.size === arr2Set.size &&
array1.every(item => arr2Set.has(item))
);
function same(arr1, arr2){
//----if you want to check by length as well
// if(arr1.length != arr2.length){
// return false;
// }
// creating an object with key => arr1 value and value => number of time that value repeat;
let frequencyCounter1 = {};
let frequencyCounter2 = {};
for(let val of arr1){
frequencyCounter1[val] = (frequencyCounter1[val] || 0) + 1;
}
for(let val of arr2){
frequencyCounter2[val] = (frequencyCounter2[val] || 0) + 1;
}
for(let key in frequencyCounter1){
//check if the key is present in arr2 or not
if(!(key in frequencyCounter2)) return false;
//check the number of times the value repetiton is same or not;
if(frequencyCounter2[key]!==frequencyCounter1[key]) return false;
}
return true;
}

Deleting Element After Pushing

If I have an array where I am pushing certain elements to a second array- how can I delete those elements from the first array after pushing them to the second? Here is sample code:
for(var a = 0; a < arr.length; a+=1){
if(arr[a].length == 4){
other.push(arr[a]);
}
}
In other words, I know longer want elements arr[a] to be in arr if they have been pushed to other.
Just do a splice on that original array index to remove that element if you no longer require it.
for(var a = 0; a < arr.length;){
if(arr[a].length == 4){
other.push(arr[a]);
arr.splice(a, 1);
}
else {
a += 1;
}
}
This seems fine:
for(var a = 0, length=arr.length; a < length; a++){
if(arr[a].length == 4){
other.push(arr[a]);
arr.splice(a,1);
}
}
Write a function which takes an input array, and a function to determine if an element should be moved. It returns a two-element array, containing the modified input, and the new array into which elements have been extracted.
function extractIf(array, condition) {
return [
array.filter(not(condition)),
array.filter( condition)
];
}
// Specify which elements are to be extracted/moved.
function condition(elt) { return elt.length === 4; }
// Little helper function to invert a function.
function not(fn) { return function() { return !fn.apply(this, arguments); }; }
Invoke this as:
var results = extractIf(arr, condition);
arr = results[0];
other = results[1];
underscore solution
If you are willing to use underscore, you could group the input by the true/false value of the condition:
var groups = _.groupBy(arr, function(elt) { return elt.length === 4; })
Your original array with the elements removed will be in groups.false, and the other array in groups.true.

How do I know an array contains all zero(0) in Javascript

I have an array. I need to generate an alert if all the array items are 0.
For example,
if myArray = [0,0,0,0];
then alert('all zero');
else
alert('all are not zero');
Thanks.
You can use either Array.prototype.every or Array.prototype.some.
Array.prototype.every
With every, you are going to check every array position and check it to be zero:
const arr = [0,0,0,0];
const isAllZero = arr.every(item => item === 0);
This has the advantage of being very clear and easy to understand, but it needs to iterate over the whole array to return the result.
Array.prototype.some
If, instead, we inverse the question, and we ask "does this array contain anything different than zero?" then we can use some:
const arr = [0,0,0,0];
const someIsNotZero = arr.some(item => item !== 0);
const isAllZero = !someIsNotZero; // <= this is your result
This has the advantage of not needing to check the whole array, since, as soon it finds a non-zero value, it will instantly return the result.
for loop
If you don't have access to modern JavaScript, you can use a for loop:
var isAllZero = true;
for(i = 0; i < myArray.length; ++i) {
if(myArray[i] !== 0) {
isAllZero = false;
break;
}
}
// `isAllZero` contains your result
RegExp
If you want a non-loop solution, based on the not-working one of #epascarello:
var arr = [0,0,0,"",0],
arrj = arr.join('');
if((/[^0]/).exec(arrj) || arr.length != arrj.length){
alert('all are not zero');
} else {
alert('all zero');
}
This will return "all zero" if the array contains only 0
Using ECMA5 every
function zeroTest(element) {
return element === 0;
}
var array = [0, 0, 0, 0];
var allZeros = array.every(zeroTest);
console.log(allZeros);
array = [0, 0, 0, 1];
allZeros = array.every(zeroTest);
console.log(allZeros);
Use an early return instead of 2, 3 jumps. This will reduce the complexity. Also we can avoid initialisation of a temp variable.
function ifAnyNonZero (array) {
for(var i = 0; i < array.length; ++i) {
if(array[i] !== 0) {
return true;
}
}
return false;
}
Using Math.max when you know for certain that no negative values will be present in the array:
const zeros = [0, 0, 0, 0];
Math.max(...zeros) === 0; // true
No need to loop, simple join and reg expression will work.
var arr = [0,0,0,10,0];
if((/[^0]/).exec(arr.join(""))){
console.log("non zero");
} else {
console.log("I am full of zeros!");
}
Another slow way of doing it, but just for fun.
var arr = [0,0,0,0,10,0,0];
var temp = arr.slice(0).sort();
var isAllZeros = temp[0]===0 && temp[temp.length-1]===0;
you can give a try to this :
var arr = [0,0,0,0,0];
arr = arr.filter(function(n) {return n;});
if(arr.length>0) console.log('Non Zero');
else console.log("All Zero");

Delete zero values from Array with JavaScript

I have an array with name "ids" and some values like ['0','567','956','0','34']. Now I need to remove "0" values from this array.
ids.remove ("0"); is not working.
Here's a function that will remove elements of an array with a particular value that won't fail when two consecutive elements have the same value:
function removeElementsWithValue(arr, val) {
var i = arr.length;
while (i--) {
if (arr[i] === val) {
arr.splice(i, 1);
}
}
return arr;
}
var a = [1, 0, 0, 1];
removeElementsWithValue(a, 0);
console.log(a); // [1, 1]
In most browsers (except IE <= 8), you can use the filter() method of Array objects, although be aware that this does return you a new array:
a = a.filter(function(val) {
return val !== 0;
});
Use splice method in javascript. Try this function:
function removeElement(arrayName,arrayElement)
{
for(var i=0; i<arrayName.length;i++ )
{
if(arrayName[i]==arrayElement)
arrayName.splice(i,1);
}
}
Parameters are:
arrayName:- Name of the array.
arrayElement:- Element you want to remove from array
Here's one way to do it:
const array = ['0', '567', '956', '0', '34'];
const filtered = array.filter(Number);
console.log(filtered);
For non-trivial size arrays, it's still vastly quicker to build a new array than splice or filter.
var new_arr = [],
tmp;
for(var i=0, l=old_arr.length; i<l; i++)
{
tmp = old_arr[i];
if( tmp !== '0' )
{
new_arr.push( tmp );
}
}
If you do splice, iterate backwards!
For ES6 best practice standards:
let a = ['0','567','956','0','34'];
a = a.filter(val => val !== "0");
(note that your "id's" are strings inside array, so to check regardless of type you should write "!=")
Below code can solve your problem
for(var i=0; i<ids.length;i++ )
{
if(ids[i]=='0')
ids.splice(i,1);
}
ids.filter(function(x) {return Number(x);});
I believe, the shortest method is
var newList = ['0', '567', '956', '0', '34'].filter(cV => cV != "0")
You could always do,
listWithZeros = ['0', '567', '956', '0', '34']
newList = listWithZeros.filter(cv => cv != "0")
The newList contains your required list.
Explanation
Array.prototype.filter()
This method returns a new array created by filtering out items after testing a conditional function
It takes in one function with possibly 3 parameters.
Syntax:
Array.prototype.filter((currentValue, index, array) => { ... })
The parameters explain themselves.
Read more here.
The easy approach is using splice!!. But there's a problem, every time you remove an element your array size will constantly reduce. So the loop will skip 1 index the array size reduces.
This program will only remove every first zero.
// Wrong approach
let num = [1, 0, 0, 2, 0, 0, 3,];
for(let i=0; i<num.length; i++){
if(num[i]==0)
num.splice(i, 1);
}
console.log(num)
the output will be
[1,0,2,0,3]
So to remove all the zeros you should increase the index if you found the non-zero number.
let i = 0;
while(i<num.length){
if(num[i]==0){
num.splice(i,1);
}
else{
i++;
}
}
But there's a better way. Since changing the size of the array only affects the right side of the array. You can just traverse in reverse and splice.
for(let i=num.length-1; i>=0; i--){
if(num[i]===0)
num.splice(i,1);
}

Categories

Resources