How do I get the difference between two FIFO array states? - javascript

I have two arrays that represent a fifo-like state, an old state and a new state. I need a function that finds the newly added items by comparing the new array with the old one. Below 3 examples of two arrays where 1 has items added to the front of it compared to the other:
// Input 1
const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr2 = ['a', 'b', 'a', 'b', 'c', 'd', 'e', 'f', 'g']; // added 'a' and 'b' in front
// Input 2
const arr3 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr4 = ['q', 'r', 'a', 'b', 'c', 'd', 'e', 'f', 'g']; // added 'q' and 'r' in front
// Input 3
const arr5 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr6 = ['a', 'b', 'q', 'a', 'b', 'c', 'd', 'e', 'f']; // added 'a' 'b' and 'q' in front
// New Input 4
const arr7 = ['a', 'b', 'a', 'b', 'c', 'd', 'e', 'f', 'g'];
const arr8 = ['a', 'b', 'a', 'b', 'a', 'b', 'c', 'd', 'e']; // added 'a' and 'b' in front
Note that the amount of newly added items is removed from the back of the array.
Here the desired functionality getItemsAdded(arr1, arr2) function:
// Desired output for 'getItemsAdded()' function
console.log(getItemsAdded(arr1, arr2)); // [ 'a', 'b' ]
console.log(getItemsAdded(arr3, arr4)); // [ 'q', 'r' ]
console.log(getItemsAdded(arr5, arr6)); // [ 'a', 'b', 'q' ]
// New
console.log(getItemsAdded(arr7, arr8)); // [ 'a', 'b' ]
It feels like such a simple problem, but I cant get my head around it.. I couldn't solve it with solutions provided here How to get the difference between two arrays in JavaScript?, since its a different problem.

Code can tell more words, Then my silly explanation...
// Input 1
const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr2 = ['a', 'b', 'a', 'b', 'c', 'd', 'e', 'f', 'g']; // added 'a' and 'b' in front
// Input 2
const arr3 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr4 = ['q', 'r', 'a', 'b', 'c', 'd', 'e', 'f', 'g']; // added 'q' and 'r' in front
// Input 3
const arr5 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
const arr6 = ['a', 'b', 'q', 'a', 'b', 'c', 'd', 'e', 'f']; // added 'a' 'b' and 'q' in front
const arr7 = ['a', 'b', 'a', 'b', 'c', 'd', 'e', 'f', 'g'];
const arr8 = ['a', 'b', 'a', 'b', 'a', 'b', 'c', 'd', 'e']; // added 'a' and 'b' in front
// Desired output for 'diff()' function
console.log([...getItemsAdded(arr1, arr2)]); // [ 'a', 'b' ]
console.log([...getItemsAdded(arr3, arr4)]); // [ 'q', 'r' ]
console.log([...getItemsAdded(arr5, arr6)]); // [ 'a', 'b', 'q' ]
console.log([...getItemsAdded(arr7, arr8)]); // [ 'a', 'b' ]
function startsWith(arr1, arr2) {
for (let i = 0; i < arr1.length; i++)
if (arr1[i] != arr2[i])
return false
return true
}
function* getItemsAdded(arr1, arr2) {
while (!startsWith(arr2, arr1)) yield arr2.shift()
}

Related

Swap two elements between two arrays in Javascript

Let's say I have two different arrays:
const a = ['a', 'b', 'c', 'd', 'e', 'f'];
and
const b = ['g', 'h', 'i', 'j', 'k', 'l'];
and I want to place 'c' on the position of 'l' and vice-versa, like so:
const a = ['a', 'b', 'l', 'd', 'e', 'f'];
const b = ['g', 'h', 'i', 'j', 'k', 'c'];
How can I achieve this?
I do it like this because I'm organizing a set of values in pages, and each page contains at max 6 elements
You could use array destructuring for swapping elements.
const a = ['a', 'b', 'c', 'd', 'e', 'f'];
const b = ['g', 'h', 'i', 'j', 'k', 'l'];
let idxC = a.indexOf('c'), idxL = b.indexOf('l');
[a[idxC], b[idxL]] = [b[idxL], a[idxC]];
console.log(JSON.stringify(a));
console.log(JSON.stringify(b));
Another way to swap elements, kind of overengeniring but forgive me
const a = ['a', 'b', 'c', 'd', 'e', 'f'];
const b = ['g', 'h', 'i', 'j', 'k', 'l'];
const pair = ['c','l'];
const divider = '//';
const aa = a.join(divider).replaceAll(...pair).split(divider);
const bb = b.join(divider).replaceAll(...pair.reverse()).split(divider);
console.log(...aa);
console.log(...bb);
.as-console-wrapper{min-height: 100%!important; top: 0}

How can I pull a value from last clicked div?

I am trying to make a boggle game in Js and I want to add some features to make life more simpler. And not having to duplicate my code a thousand times. Basically I have a function called addLetter() which simply pushes the letter clicked on to an array. It only works for one letter right now and I dont want to hardcode it. So how can I pull the value from the clicked div? I dont want to make 16 functions to push one letter from a single div.
Source code:
var letters = [];
const random = Math.floor(Math.random() * 6);
var dice1 = ['R', 'I', 'F', 'O', 'B', 'X'];
var dice2 = ['I', 'F', 'E', 'H', 'E', 'Y'];
var dice3 = ['D', 'E', 'N', 'O', 'W', 'S'];
var dice4 = ['U', 'T', 'O', 'K', 'N', 'D'];
var dice5 = ['H', 'M', 'S', 'R', 'A', 'O'];
var dice6 = ['L', 'U', 'P', 'E', 'T', 'S'];
var dice7 = ['A', 'C', 'I', 'T', 'O', 'A'];
var dice8 = ['Y', 'L', 'G', 'K', 'U', 'E'];
var dice9 = ['Q', 'B', 'M', 'J', 'O', 'A'];
var dice10 = ['E', 'H', 'I', 'S', 'P', 'N'];
var dice11 = ['V', 'E', 'T', 'I', 'G', 'N'];
var dice12 = ['B', 'A', 'L', 'I', 'Y', 'T'];
var dice13 = ['E', 'Z', 'A', 'V', 'N', 'D'];
var dice14 = ['R', 'A', 'L', 'E', 'S', 'C'];
var dice15 = ['U', 'W', 'I', 'L', 'R', 'G'];
var dice16 = ['U', 'W', 'I', 'L', 'R', 'G'];
var dice1rnd = (dice1[random]);
var dice2rnd = (dice2[random]);
var dice3rnd = (dice3[random]);
var dice4rnd = (dice4[random]);
var dice5rnd = (dice5[random]);
var dice6rnd = (dice6[random]);
var dice7rnd = (dice7[random]);
var dice8rnd = (dice8[random]);
var dice9rnd = (dice9[random]);
var dice10rnd = (dice10[random]);
var dice11rnd = (dice11[random]);
var dice12rnd = (dice12[random]);
var dice13rnd = (dice13[random]);
var dice14rnd = (dice14[random]);
var dice15rnd = (dice15[random]);
var dice16rnd = (dice16[random]);
console.log(dice1[random]);
console.log(dice2[random]);
console.log(dice3[random]);
console.log(dice4[random]);
console.log(dice5[random]);
console.log(dice6[random]);
console.log(dice7[random]);
console.log(dice8[random]);
console.log(dice9[random]);
console.log(dice10[random]);
console.log(dice11[random]);
console.log(dice12[random]);
console.log(dice13[random]);
console.log(dice14[random]);
console.log(dice15[random]);
console.log(dice16[random]);
console.log(letters);
document.getElementById('dice1rnd').innerHTML = dice1rnd;
document.getElementById('dice1rnd').addEventListener("click", addLetter, false);
document.getElementById('dice2rnd').innerHTML = dice2rnd;
document.getElementById('dice3rnd').innerHTML = dice3rnd;
document.getElementById('dice4rnd').innerHTML = dice4rnd;
document.getElementById('dice5rnd').innerHTML = dice5rnd;
document.getElementById('dice6rnd').innerHTML = dice6rnd;
document.getElementById('dice7rnd').innerHTML = dice7rnd;
document.getElementById('dice8rnd').innerHTML = dice8rnd;
document.getElementById('dice9rnd').innerHTML = dice9rnd;
document.getElementById('dice10rnd').innerHTML = dice10rnd;
document.getElementById('dice11rnd').innerHTML = dice11rnd;
document.getElementById('dice12rnd').innerHTML = dice12rnd;
document.getElementById('dice13rnd').innerHTML = dice13rnd;
document.getElementById('dice14rnd').innerHTML = dice14rnd;
document.getElementById('dice15rnd').innerHTML = dice15rnd;
document.getElementById('dice16rnd').innerHTML = dice16rnd;
document.getElementById('demo').innerHTML = letters;
function addLetter() {
letters.push(dice1rnd);
document.getElementById('demo').innerHTML = letters;
}
Are you trying to do something like this?
You don't need nearly so many variables — use arrays, map, and forEach loops instead.
Also, your random only gets calculated once, so it will always be the same. If you put it in a function (() => ...) it becomes callable (random()) so you can generate many different values.
const random = () => Math.floor(Math.random() * 6);
const dice = [
['R', 'I', 'F', 'O', 'B', 'X'],
['I', 'F', 'E', 'H', 'E', 'Y'],
['D', 'E', 'N', 'O', 'W', 'S'],
['U', 'T', 'O', 'K', 'N', 'D'],
['H', 'M', 'S', 'R', 'A', 'O'],
['L', 'U', 'P', 'E', 'T', 'S'],
['A', 'C', 'I', 'T', 'O', 'A'],
['Y', 'L', 'G', 'K', 'U', 'E'],
['Q', 'B', 'M', 'J', 'O', 'A'],
['E', 'H', 'I', 'S', 'P', 'N'],
['V', 'E', 'T', 'I', 'G', 'N'],
['B', 'A', 'L', 'I', 'Y', 'T'],
['E', 'Z', 'A', 'V', 'N', 'D'],
['R', 'A', 'L', 'E', 'S', 'C'],
['U', 'W', 'I', 'L', 'R', 'G'],
['U', 'W', 'I', 'L', 'R', 'G'],
]
const randomize = () => {
const results = dice.map(die => die[random()])
document.querySelectorAll('.result').forEach((el, idx) => {
el.textContent = results[idx]
})
}
randomize()
document.querySelector('#btn').addEventListener('click', randomize)
.row {
display: flex;
font-family: monospace;
}
.result {
width: 2em;
height: 2em;
}
<div class="row"> <div class="result"></div><div class="result"></div><div class="result"></div><div class="result"></div></div><div class="row"> <div class="result"></div><div class="result"></div><div class="result"></div><div class="result"></div></div><div class="row"> <div class="result"></div><div class="result"></div><div class="result"></div><div class="result"></div></div><div class="row"> <div class="result"></div><div class="result"></div><div class="result"></div><div class="result"></div></div>
<button id="btn">Randomize</button>
To directly address your concern, you can use target prop of the event that is passed to your method to make it dynamic.
https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
example:
function addLetter (event) {
console.log(event.target.innerHTML) // => should print contents of clicked div.
}

What is the best way to concatenate a multidimensional array in Javascript? [duplicate]

This question already has answers here:
Merge/flatten an array of arrays
(84 answers)
Closed 3 years ago.
I want to populate an autocomplete search box.
I am using this, but is there a better way?
var array1 = [
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i']
];
console.log(array1[0].concat(array1[1], array1[2]));
One option is using flat()
var array1 = [
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i']
];
console.log( array1.flat() );
Or concat and spread syntax
var array1 = [
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i']
];
console.log( [].concat(...array1) )

create an matrix of an array from the given string

I am trying to create an matrix of array from given string ('bananabar'). each matrix element should have made from taking one string element off at last and append upfront.
for example: first array would be ['b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r'] and next matrix array would be ['r','b', 'a', 'n', 'a', 'n', 'a', 'b', 'a'].
Here is my function:
function createTable(s) {
var strArr = s.split('');
var arr = [];
for (i=0; i<s.length; i++) {
arr[i] = strArr;
console.log(arr[i])
strArr.unshift(strArr.pop());
}
console.log(arr, 'arr')
return arr;
}
when I console logged the arr[i] withing for loop to see if taking one array element from strArr off and append it upfront, and it shows up correct. following is console log statement within for loop.
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ]
[ 'r', 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a' ]
[ 'a', 'r', 'b', 'a', 'n', 'a', 'n', 'a', 'b' ]
[ 'b', 'a', 'r', 'b', 'a', 'n', 'a', 'n', 'a' ]
[ 'a', 'b', 'a', 'r', 'b', 'a', 'n', 'a', 'n' ]
[ 'n', 'a', 'b', 'a', 'r', 'b', 'a', 'n', 'a' ]
[ 'a', 'n', 'a', 'b', 'a', 'r', 'b', 'a', 'n' ]
[ 'n', 'a', 'n', 'a', 'b', 'a', 'r', 'b', 'a' ]
[ 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r', 'b' ]
however when I console logged returned result it shows following arrays of array:
[ [ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ],
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ],
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ],
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ],
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ],
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ],
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ],
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ],
[ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ] ]
but I wanted output in the following way
[ [ 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r' ]
[ 'r', 'b', 'a', 'n', 'a', 'n', 'a', 'b', 'a' ]
[ 'a', 'r', 'b', 'a', 'n', 'a', 'n', 'a', 'b' ]
[ 'b', 'a', 'r', 'b', 'a', 'n', 'a', 'n', 'a' ]
[ 'a', 'b', 'a', 'r', 'b', 'a', 'n', 'a', 'n' ]
[ 'n', 'a', 'b', 'a', 'r', 'b', 'a', 'n', 'a' ]
[ 'a', 'n', 'a', 'b', 'a', 'r', 'b', 'a', 'n' ]
[ 'n', 'a', 'n', 'a', 'b', 'a', 'r', 'b', 'a' ]
[ 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r', 'b' ] ]
see if you can figure out what's causing the issue.
The reason you are having this problem is that you are pushing a reference to the same array into your matrix and then altering the same array over and over again. Each time you push and unshift you are doing it to every row in the matrix because they are all references to the same array.
There are lots of other ways to do this, but to illustrate the problem, here's your original code with one small change. It uses slice() to make a copy of the array before pushing into the matrix:
let strArr = ['b', 'a', 'n', 'a', 'n', 'a', 'b', 'a', 'r']
var arr = strArr.slice();
for (i=0; i<strArr.length; i++) {
arr[i] = strArr.slice(); // copy the array
strArr.unshift(strArr.pop());
}
console.log(arr.map(row => row.join(',')))
Here is a way to do it by using Array.from() twice and String.prototype.charAt():
const makeMatrix = s =>
Array.from({ length: s.length }, (_, i) =>
Array.from({ length: s.length }, (_, j) =>
s.charAt((j - i + s.length) % s.length)));
console.log(JSON.stringify(makeMatrix('bananabar')));

Better way to iterate over array and append to html using js or jquery

I am wondering if there is a shorter/better way to iterate through an array that contains {key:[array],key2:[array]}
var ray = {'A':['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'],
'B': ['m', 'n', 'b', 'v', 'c', 'x', 'z'],
'C': ['o', 'i', 'd', 'f', 'j', 'a', 'l', 'a', 'd']
}
At the moment I have
function(data) {
var ray = data.result;
$.each(ray, function() {
if(this == ray.A){
$.each(this, function(i, v) {
$("#list1").append('<span class="tag">' + v + "</span>");
});
}
if(this == ray.B){
$.each(this, function(i, v) {
$("#list2").append('<span class="tag2">' + v + "</span>");
});
}
});
}
etc..
is there a better way to do this without the excessive duplication ?
As per your data type, you may do as follows in general...
Object.keys(ray).forEach(k => ray[k].forEach(e => doSomethingWith(k,e)))
Use $("#list"+j).append with looping as the list has same name.
var ray = {'A':['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'],
'B': ['m', 'n', 'b', 'v', 'c', 'x', 'z'],
'C': ['o', 'i', 'd', 'f', 'j', 'a', 'l', 'a', 'd']
}
function arr() {
var j=0;
$.each(ray, function() {
j++;
$.each(this, function(i, v) {
$("#list"+j).append('<span class="tag">' + v + "</span>");
});
});
}
arr();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="list1">
</div>
<div id="list2">
</div>
<div id="list3">
</div>

Categories

Resources