Swap two elements between two arrays in Javascript - 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}

Related

I want to sort my words from arr by 2nd letter of each word according to my given pattern

/*
pattern:
e,b,c,d,i,f,g,h,o,j,k,l,m,n,u,p,q,r,s,t,a,v,w,x,y,z
I want to sort my words from arr by 2nd letter of each word according to my given pattern.
['aobcdh','aiabch','obijkl']
#output should be:
obijkl
aiabch
aobcdh
*/
// I tried this way:
let pattern = ['e', 'b', 'c', 'd', 'i', 'f', 'g', 'h', 'o', 'j', 'k', 'l', 'm', 'n', 'u', 'p', 'q', 'r', 's', 't', 'a', 'v', 'w', 'x', 'y', 'z']
let arr = ['aiabch', 'aobcdh', 'obijkl', 'apcsdef', 'leeeeeeeeeeeeeeee']
let refArr = []
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < pattern.length; j++) {
if (pattern[j] === arr[i][1]) {
refArr.push(j)
}
}
}
console.log(refArr)
// now what next?
You can use the sort method and the indexOf function
let pattern = ['e', 'b', 'c', 'd', 'i', 'f', 'g', 'h', 'o', 'j', 'k', 'l', 'm', 'n', 'u', 'p', 'q', 'r', 's', 't', 'a', 'v', 'w', 'x', 'y', 'z']
let arr = ['aiabch', 'aobcdh', 'obijkl', 'apcsdef', 'leeeeeeeeeeeeeeee']
const newArr = arr.sort((a, b) => pattern.indexOf(a[1]) - pattern.indexOf(b[1]))
console.log(newArr)
You could generate an object with the order values and sort by this values.
If necessary convert the key to lower case and/or take a default value for sorting unknown letters to front or end.
const
pattern = 'ebcdifghojklmnupqrstavwxyz',
array = ['aobcdh', 'aiabch', 'obijkl'],
order = Object.fromEntries(Array.from(pattern, (l, i) => [l, i + 1]));
array.sort((a, b) => order[a[1]] - order[b[1]]);
console.log(array);
Also, you can try this if you does not know Array methods.
let pattern = ['e', 'b', 'c', 'd', 'i', 'f', 'g', 'h', 'o', 'j', 'k', 'l', 'm', 'n', 'u', 'p', 'q', 'r', 's', 't', 'a', 'v', 'w', 'x', 'y', 'z'], arr = ['aiabch', 'aobcdh', 'obijkl', 'apcsdef', 'leeeeeeeeeeeeeeee'], refArr = []
arr.forEach(a => pattern.includes(a[2]) ? refArr.push(a) : null)
console.log(refArr)
You must reverse your cross loops:
for(let i = 0; i < pattern.length; ++i) {
for(let j = 0; j < arr.length; ++j) {
if(pattern[i] === arr[j][1]) refArr.push(arr[j]);
}
}

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

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()
}

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.
}

Pick 5 random letters from array

For school I need to make a script that prints 3 times something with 5 random letters. "ajshw kcmal idksj"
I have made this:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z'];
var random = myArray[Math.floor(Math.random() * myArray.length)];
document.write('<br>' + random);
But this only prints one letter. How can it print 5 letters 3 times?
Iterate 5 times to generate each word with 5 letters and iterate 3 times to generate three words. You can use for loop to generate the words or you can use array#map to generate the words and using array#join you can join them.
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
random = [...Array(3)]
.map(_ => [...Array(5)].map(_ => myArray[Math.floor(Math.random() * myArray.length)]).join(''))
.join('<br>');
document.write(random);
What about just making a nested loop:
const myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z'
];
const length = myArray.length;
const numStrings = 3;
const numLetters = 5;
for (let i = 0; i < numStrings; i++) {
let string = "";
for (let j = 0; j < numLetters; j++) {
let letter = myArray[Math.floor(Math.random() * length)];
string += letter;
}
console.log(string);
}
A simple way would be to simply generate that single letter multiple times with a loop. A way to do this would go as follows:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z'];
var phrase = "";
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 5; y++) {
phrase = phrase + myArray[Math.floor(Math.random() * myArray.length)];
}
phrase = phrase + " ";
}
console.log(phrase)

How do I split an array with 26 different string values, that appear as 1 string on a webpage?

var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var letters = document.createElement("ul");
letters.innerHTML = alphabet;
// This is to split the array "alphabet" into individual strings
var separatedLetters = document.getElementById("letters");
separatedLetters.appendChild(letters);
this is the code I used to attempt to split the string,
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
and that is how it appeared on my web page, it displays as one whole string instead of each letter being a string.
Something like the follow? Since you are using an unordered list, I am assuming you would want each character on its own bullet
var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var ul = document.createElement("ul");
for(var i = 0; i < alphabet.length; ++i) {
var li = document.createElement("li");
li.innerText = alphabet[i];
ul.appendChild(li);
}
document.body.appendChild(ul);
Here an example:
var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var string = alphabet.join("");// <--- array to string ABCDEFGHIJKLMNOPQRSTUVWXYZ
console.log(string);
var alphabet = string.split("");// <--- string to array
console.log(alphabet);
As mentioned, you should wrap every letter with li and append each element to the list.
Additionally, in order not to cause unnecessary reflows, you can utilize Document.createDocumentFragment()
HTML:
<div id="letters"></div>
JS:
var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var separatedLetters = document.getElementById("letters");
var fragment = document.createDocumentFragment();
fragment.appendChild(document.createElement('ul'));
alphabet.forEach(letter => {
var li = document.createElement('li');
li.textContent = letter;
fragment.childNodes[0].appendChild(li);
});
separatedLetters.appendChild(fragment);

Categories

Resources