Array conversion? - javascript

I'm really new to javascript, and when trying to achieve the following I stumbled upon some problems. I tried searching the forum - and a problem like this is probably something that has been solved before, but I don't know what to search for. This is also the reason for the extremely creative title:/
Anyhow - this is my current code:
var arraylength = 4;
var originalarray = new Array(new Array);
var originalarray = {
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]
[4, 4, 4, 4]
}
convertarray(originalarray, arraylength);
function convertarray(originalarray, arraylength){
var converedtarray = new Array(new Array);
var temparray = new Array;
temparray.length = arraylength;
for (h = 0; h < arraylength; h++) {
var temparray = [];
var temparray = originalarray[h].split('');
for (i = 0; i < arraylength; i++) {
converedtarray[h][i] = temparray[i];
}
}
return convertedarray;
}
I am not entirely sure if the code speaks for itself, but this is pseudo for what I want to achieve;
originalarray = 1111, 2222, 3333, 4444
converedtarray = 1234, 1324, 1234, 1234
Can someone tell me what part I've missed or give me a hint of what I can do?
Because I'm getting "TypeError: undefined is not an object" at this part:
converedtarray[h][i] = temparray[i];
I am by no means a professional coder - I know the code isn't pretty, but this is more or less the result of trial-and error... More error than trial actually.
Thank you in advance for your answer!

A possible solution:
var arraylength = 4;
var originalarray = [
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4],
];
function convertarray(originalarray, arraylength) {
var result = [];
for (h = 0; h < arraylength; h++) {
result.push(
originalarray.map(function(subarray) {
return subarray[h];
})
);
}
return result;
}
console.log(
convertarray(originalarray, arraylength)
);

There are a few problems with your code. Firstly if you want a nXn array you have defined originalarray wrong. Second new Array(new Array) won't declare an array of array for you if that is what you were thinking. You will need two loops here as you have already figured out the first one for maintaining columns and the second one for rows.
var arraylength = 4;
var originalarray = new Array();
var originalarray = [
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]
]
console.log(convertarray(originalarray, arraylength));
function convertarray(originalarray, arraylength){
var converedtarray = new Array();
for (h = 0; h < arraylength; h++) {
converedtarray[h] = [];
for (i = 0; i < arraylength; i++) {
converedtarray[h].push(originalarray[i][h]);
}
}
return converedtarray;
}

Related

How to create nested array of different length from a multidimensional array

I have an array that looks like this:
arr = [[1,2,3],
[4,5,6],
[7,8,9]]
I have initialized an empty array and I want put the diagonals of the arr inside the new array. So i've tried this:
arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
new_arr = [];
tail = arr.length - 1;
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
if (j == i) {
new_arr.push(arr[i][j]);
}
if (j == tail) {
new_arr.push(arr[i][j]);
tail--;
}
}
}
console.log(new_arr)
The logic seems to work but I can't seem to get the structure right. What I want is to nest two arrays inside the new array like this:
[[1,5,9],[3,5,7]]
But what I get is one array with the right values unordered. How to get the expected output? Any help is appreciated. Thanks!
You need to have 2 separate temporary arrays. And you don't need nested loops. You can optimize the code like this with a single loop if you understand the math.
arr = [[1,2,3],
[4,5,6],
[7,8,9]];
function findDiagonals(arr) {
const diagonal_1 = [];
const diagonal_2 = [];
for( let i = 0; i < arr.length; i++ ) {
diagonal_1.push(arr[i][i]);
diagonal_2.push(arr[i][arr.length - (i+1)]);
}
return [diagonal_1, diagonal_2];
}
console.log(findDiagonals(arr));
var arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
var diagonal1 = [];
var diagonal2 = [];
for (var i = 0; i < arr.length; i++) {
diagonal1.push(arr[i][i]);
diagonal2.push(arr[i][arr.length - i - 1]);
}
var new_arr = [diagonal1, diagonal2];
console.log(new_arr)
The following solution would work for you if the width and height of the number matrix is always equal.
const arr = [[1,2,3],
[4,5,6],
[7,8,9]];
const result = [[],[]];
arr.map((row,index) => {
result[0].push(row[0+index]);
result[1].push(row[row.length - index - 1]);
});
console.log(result); // [[1,5,9],[3,5,7]]
This is a O(n) approach by using the function Array.prototype.reduce.
const arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
const result = arr.reduce(([left, right], array, row, {length}) => {
return [[...left, array[row]], [...right, array[length - row - 1]]];
}, [[],[]]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
the difficulty is low:
const
arr = [[1,2,3],[4,5,6],[7,8,9]]
, new_arr = [[],[]]
;
let p0 = 0, p1 = arr.length
for( let inArr of arr)
{
new_arr[0].push( inArr[p0++] )
new_arr[1].push( inArr[--p1] )
}
console.log( JSON.stringify( new_arr ))
in a one Line code:
const
arr = [[1,2,3],[4,5,6],[7,8,9]]
, new_arr = arr.reduce(([lft,rgt],A,i,{length:Sz})=>([[...lft,A[i]],[...rgt,A[Sz-i-1]]]),[[],[]])
;
console.log( JSON.stringify( new_arr )) // [[1,5,9],[3,5,7]]

Array is not defined - Codewars Kata Round Robin Tournament

I am attempting to do this Kata - https://www.codewars.com/kata/organize-a-round-robin-tournament/train/javascript.
The task is to create a function that organizes a round robin tournament.
Example:
buildMatchesTable(4)
Should return a matrix like:
[
[[1,2], [3, 4]], // first round: 1 vs 2, 3 vs 4
[[1,3], [2, 4]], // second round: 1 vs 3, 2 vs 4
[[1,4], [2, 3]] // third round: 1 vs 4, 2 vs 3
]
I have created a very clunky solution that works up until the last hurdle. I am left with an array (arr6) that is an array listing all the matchups in the correct order, but as a simple array, not subarrays designating the various rounds. So I tried to create a function cut to produce an array in the correct format and it tells me arr7 is not defined.
My solution is poorly written as I am new to this, but I think the fix should be relatively simple, something to do with not returning values correctly in functions, or functions called in the wrong order. Thanks.
function buildMatchesTable(numberOfTeams) {
let n = numberOfTeams; let h = n/2; let arr = []; let arr2 = [[],[]];
let arr3 = [...Array(n-1)].map(v => v); let arr4 = [];
//create array
for (var i = 1; i <= n; i++) {arr.push(i)} //[1, 2, 3, 4]
//split array
arr2[0] = arr.splice(0, arr.length/2);
arr2[1] = arr.splice(0, arr.length); //[[1, 2], [3, 4]]
//create a function that produces matches in a round from array[i]
function round (arr2) {
for (var i = 0; i < arr2[0].length; i++){
arr4.push([arr2[0][i], arr2[1][i]]);
}
arr2 = arr4;
return arr2; // [[1 v 3], [2 v 4]] etc.
}
//create a function that tranforms the arr to gameweek +1 (rotate everything clockwise apart from team 1
function trans(arr2){
//create new arr5 that is the same as arr2
arr5 = [[],[]];
for (var i = 0; i < arr2[0].length; i++) {
arr5[0].push(arr2[0][i])
arr5[1].push(arr2[1][i])
}
//rotate every element apart from arr2[0,0] : [[1, 3], [4, 2]]
let h = arr2[0].length - 1;
arr2[0][1] = arr5[1][0];
arr2[1][h] = arr5[0][h];
for (var i = 2; i <= h; i++){
arr2[0][i] = arr5[0][i-1];}
for (var i = 0; i <= h-1; i++){
arr2[1][i] = arr5[1][i+1];}
return arr2;
}
function final (n, arr2, arr3){ //putting all the functions together
for (var i = 0; i < n-1; i++){
arr3[i] = (round(arr2));
trans(arr2);
}
return arr3; // [[1, 3], [2, 4, [1, 4], [3, 2], [1, 2], [4, 3]] X 3
}
final(n, arr2, arr3)
let arr6 = arr3[0]; // arr6 = [[1, 3], [2, 4, [1, 4], [3, 2], [1, 2], [4, 3]]
function cut(arr6, n) {
let arr7 = [];
let index = 0;
while (index < arr6.length) {
arr7.push(arr6.slice(index, n/2+index));
index += n/2;
}
return arr7;
}
cut(arr6, n);
console.log(n);
console.log(arr);
console.log(arr2);
console.log(arr3[0]);
console.log(arr4);
console.log(arr6);
console.log(arr7);//not working!
//return arr7
}
buildMatchesTable(6)
No wonder, you are declaring let arr7 = []; inside a function. Get it out of the function, on the same level as arr6, arr4, etc.

Create new loop for duplicate index with Javascript

Quick question. I need to create an array using duplicated index. For example, I have an array like:
var array = [2, 3, 2, 4, 3, 2, 6, 7];
And I need to get a new loop interaction for each duplicate index, the response should be something like:
[
[2, 3, 4, 6, 7],
[2, 3],
[2],
]
Please let me know if is possible and how to create some function to do it.
Thank you!
You can just use one object to store number of occurrences for each element and use that value to create result array.
var array = [2, 3, 2, 4, 3, 2, 6, 7];
var obj = {}, result = []
array.forEach(function(e) {
obj[e] == undefined ? obj[e] = 0 : obj[e] += 1;
result[obj[e]] = (result[obj[e]] || []).concat(e)
})
console.log(JSON.stringify(result))
you can do something like this
var array = [2, 3, 2, 4, 3, 2, 6, 7];
array.sort();
let idx = 0, result = [];
for(let i=0; i<array.length; i++){
if(i>0 && array[i] != array[i-1]){
idx = 0;
}
if(idx == result.length)
result[idx] = [];
result[idx].push(array[i]);
idx++;
}
console.log(result);

Javascript: How to find first duplicate value and return its index?

I have to find first duplicate value in array and then return its index in variable firstIndex. This has to be done with for loop which should stop after having found first duplicate. I know this is probably pretty simple but I got stuck. So far I have this but it doesn't seem to be working:
var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3];
var firstIndex = "";
for (var a = 0; a < numbers4.length; a++) {
for (var b = a+1; b < numbers4.length; b++) {
if (numbers4[a] === numbers4[b])
firstIndex = numbers4.indexOf(numbers4[a]);
break;
}
}
console.log(firstIndex);
Console prints out 1 which is fine because 2 is first duplicate, but when I change numbers in array, the loop doesn't work. Can you advise what can be changed here?
Thanks in advance!
If I correctly understand your question, that's should help you...
Basically, you need for a double iteration.
const firstDupeIndex = list => list.findIndex(
(item, index) => list.lastIndexOf(item) !== index
);
console.log(
"First Dupe at index:",
firstDupeIndex([5, 2, 3, 4, 4, 6, 7, 1, 2, 3])
);
Thee above implementation comes with the drawback of being O(n2), due to nesting the lastIndexOf within the findIndex function.
A better solution would be to index your occurrences by building a dictionary, therefore keeping time complexity to just O(n) in the worst case. Probably a little bit less neat, but surely more efficient with big inputs.
const firstDupeIndex = (list) => {
const dict = {};
for (const [index, value] of list.entries()) {
if (dict.hasOwnProperty(value)) {
return dict[value];
}
dict[value] = index;
}
return -1;
};
console.log(
"First Dupe at index:",
firstDupeIndex(['a', 'b', 'c', 'd', 'e', 'b', 'z', 't', 'c'])
);
Change your code with the following
var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3];
var firstIndex = "";
var isMatch=false;
for (var a = 0; a < numbers4.length; a++) {
for (var b = a+1; b < numbers4.length; b++) {
if (numbers4[a] === numbers4[b]){
firstIndex = numbers4.indexOf(numbers4[a]);
isMatch=true;
break;
}
}
if (isMatch) {break;}
}
console.log(firstIndex);
I would use an object remembering the values already found... Something like that should work ;)
var numbers4 = [5, 2, 3, 4, 4, 6, 7, 1, 2, 3];
function findFirstDuplicateIndex(arr){
var found = {};
for (var a = 0, aa = arr.length; a < aa ; a++) {
if (found[arr[a]])
return found[arr[a]];
found[numbers4[a]] = a
}
}
console.log(findFirstDuplicateIndex(numbers4));
It's quite fast because you just loop one time through the array. The rest of the time you just access an object property or you set the object property... Let me know if you have questions ;)
However maybe there something faster... It's just an idea ^^
PS: It also works with words, not just numbers
Your break; terminates b loop, because if() is not using parenthesis {}.
Additionally, firstIndex should be simply set to either a or b depending on whether you need to return the duplicate's first occurance or first repetition.
It should be:
if (numbers4[a] === numbers4[b])
{
firstIndex = a;
break;
}
Your problem is - you have two loops and only one break, you need to break out of both.
Why not simply return the index as soon as values match?
var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3];
function getDuplicate(numbers4)
{
for (var a = 0; a < numbers4.length; a++) {
for (var b = a+1; b < numbers4.length; b++) {
if (numbers4[a] === numbers4[b]){
return a;
}
}
}
}
console.log(getDuplicate(numbers4 ));
However, you can optimize your code further by keeping a map
function getDuplicate( numbers )
{
var map = {};
for (var a = 0; a < numbers.length; a++)
{
if( map[ numbers[ a ] ] )
{
return a;
}
map[ numbers[ a ] ] = true;
}
return -1;
}
You can check if indexOf() is not equal to lastIndexOf() and return value and break loop
var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3];
var firstIndex = "";
for (var i = 0; i < numbers4.length; i++) {
if (numbers4.indexOf(numbers4[i]) != numbers4.lastIndexOf(numbers4[i])) {
firstIndex = i;
break;
}
}
console.log(firstIndex)
You don't even need nested for loops.
var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3];
var firstIndex = "";
for (var a = 1; a < numbers4.length; a++) { //start from second elem since first is never a duplicate
if (numbers4.lastIndexOf(numbers4[a])> a) {
firstIndex = a;
break;
}
}
console.log(firstIndex); //1
All you have to do during iterating is to check if current value exists somewhere further in array. That is done by checking last index of this value's occurrence using lastIndexOf().
var numbers = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3];
var firstIndex;
var len = numbers.length;
for (var i = 0; i < len; i++) {
var tmpArray = numbers.slice(i + 1, len);
var index = tmpArray.indexOf(numbers[i]);
if (index !== -1) {
firstIndex = index + i + 1;
break;
}
}
console.log(firstIndex);
Update:
Actually your logic is right, but you missed braces for if condition and also if the condition satisfies then it means firstIndex is the same as a
This is your code with braces,
var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3];
var firstIndex = "";
for (var a = 0; a < numbers4.length; a++) {
for (var b = a + 1; b < numbers4.length; b++) {
if (numbers4[a] === numbers4[b]) {
firstIndex = a
break;
}
}
}
console.log(firstIndex);
The question states the first dupe in the array has to be found along with it's index. So I return an object where the i property is the index and the e property is the first duplicate element itself. One way of performing this task would be
var numbers4 = [5, 2, 3, 4, 2, 6, 7, 1, 2, 3],
headDupe = (a,r={}) => (r.e = a.find((n,i) => (r.i = a.indexOf(n), r.i < i)),r);
console.log(headDupe(numbers4));

Add element to existing object with index and value

I would like to iterate through two arrays subtracting one arrays value from another and adding their specific difference values to an object. So for example I have:
var answer = [];
var boom = [1,2,3,4];
var other = [[1,2,3,4],
[2,3,4,5],
[6,7,8,9];
for(var i=0; i<other.length; i++) {
for(var e=0; e<4; e++){
answer[e] = boom[e] - other[i][e];
}
}
This give me an output of:
Object {0: -5, 1: -5, 2: -5, 3: -5}
Which is boom subtracted from the last array in other what I am looking for and I think I am very close to getting it is:
Object [{0: [ 0, 0, 0, 0]},
{1: [-1,-1,-1,-1]},
{2: [-5,-5,-5,-5]}];
You can see that it will add the results of each iteration of the second for loop to the object answer. How can I accomplish this?
for(var i=0; i<other.length; i++) {
answer[i] = [];
for(var e=0; e<4; e++){
answer[i][e] = boom[e] - other[i][e];
}
}
You need to initialize answer as an object not an as array, also you need to create a new answer array representing each set of values in other
var answer = {};
var boom = [1, 2, 3, 4];
var other = [
[1, 2, 3, 4],
[2, 3, 4, 5],
[6, 7, 8, 9]
];
for (var i = 0; i < other.length; i++) {
var temp = answer[i] = {};
for (var e = 0; e < 4; e++) {
temp[e] = boom[e] - other[i][e];
}
}
Demo: Fiddle

Categories

Resources