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')));
Related
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()
}
This question already has answers here:
To find Index of Multidimensional Array in Javascript
(7 answers)
Closed 3 years ago.
I want to where is placed an element in an multidimentional array like that :
var letterVariations = [
[' ','0','1','2','3','4','5','6','7','8','9'],
['A','a','B','b','C','c','D','d','E','e',';'],
['Â','â','F','f','G','g','H','h','Ê','ê',':'],
['À','à','I','i','J','j','K','k','È','è','.'],
['L','l','Î','î','M','m','N','n','É','é','?'],
['O','o','Ï','ï','P','p','Q','q','R','r','!'],
['Ô','ô','S','s','T','t','U','u','V','v','“'],
['W','w','X','x','Y','y','Ù','ù','Z','z','”'],
['#','&','#','[','(','/',')',']','+','=','-'],
];
var coordinates = letterVariations.indexOf('u');
console.log(coordinates);
// Want to know that 'u' is 7 in the 7th array
Is it possible ?
Run a simple for loop and check if the character exists in the inner array using indexOf. return immediately once a match is found
var letterVariations = [
[' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', ';'],
['Â', 'â', 'F', 'f', 'G', 'g', 'H', 'h', 'Ê', 'ê', ':'],
['À', 'à', 'I', 'i', 'J', 'j', 'K', 'k', 'È', 'è', '.'],
['L', 'l', 'Î', 'î', 'M', 'm', 'N', 'n', 'É', 'é', '?'],
['O', 'o', 'Ï', 'ï', 'P', 'p', 'Q', 'q', 'R', 'r', '!'],
['Ô', 'ô', 'S', 's', 'T', 't', 'U', 'u', 'V', 'v', '“'],
['W', 'w', 'X', 'x', 'Y', 'y', 'Ù', 'ù', 'Z', 'z', '”'],
['#', '&', '#', '[', '(', '/', ')', ']', '+', '=', '-'],
];
function getCoordinates(array, char) {
for (let i = 0; i < array.length; i++) {
const i2 = array[i].indexOf(char);
if (i2 !== -1)
return [i, i2]
}
return undefined
}
console.log(getCoordinates(letterVariations, 'u'))
console.log(getCoordinates(letterVariations, '#'))
Note: This returns the indexes and it is zero-based. If you want [7, 7], you need to return [i+1, i2]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
const letterVariations = [
[' ','0','1','2','3','4','5','6','7','8','9'],
['A','a','B','b','C','c','D','d','E','e',';'],
['Â','â','F','f','G','g','H','h','Ê','ê',':'],
['À','à','I','i','J','j','K','k','È','è','.'],
['L','l','Î','î','M','m','N','n','É','é','?'],
['O','o','Ï','ï','P','p','Q','q','R','r','!'],
['Ô','ô','S','s','T','t','U','u','V','v','“'],
['W','w','X','x','Y','y','Ù','ù','Z','z','”'],
['#','&','#','[','(','/',')',']','+','=','-'],
];
function getIndexOfLetter(letter) {
return letterVariations.reduce((result, values, index) => {
if (result[0] > -1) return result;
const found = values.indexOf(letter);
return found > -1 ? [Number(index), found] : result;
}, [-1, -1])
}
console.log(getIndexOfLetter('k'))
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);
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>
I am trying to create an text encrypter, but when i entered this code, nothing happens. What is wrong with my code?
function Encrypt(txt) {
var chars = {'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'}
for (i = 0; i < txt.length; i++) {
var chr = txt.charAt(i);
var pos = chars.indexOf(chr);
if (pos == chars.length) {
pos = 0;
}
else {
pos = pos++
}
txt.charAt(i) = chars[pos];
}
alert(txt);
}
You need
array [] instead of object {},
some declared variables
an empty result string newText, a string is read only with the character access
a valid check if the letter is not in the array
increment pos without assignment.
append the result string with the encoded character
function Encrypt(txt) {
var chars = ['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'],
i, newText = '', chr, pos;
for (i = 0; i < txt.length; i++) {
chr = txt[i];
pos = chars.indexOf(chr);
if (!~pos) {
pos = 0;
} else {
pos++;
}
newText += chars[pos];
}
document.write(newText);
}
Encrypt('test');
Because this is not an array, but object... and object has to have "index" : "value" structure.
Change this:
var chars = {'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'}
to this:
var chars = ['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']
Not considering the errors well described in the other answers, my proposal to encrypt a string is:
function Encrypt(txt) {
var chars = ['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 txtResult = txt.split('').map(function(val) {
var pos = chars.indexOf(val);
return chars[(pos == chars.length) ? 0 : (pos + 1)];
}).join('');
document.write(txtResult);
}
Encrypt('gaemaf');