Let's say I have two arrays:
var a = [[1, 10], [2, 10], [3, 10], [4, 10], [5, 10]];
var b = [[1, 20], [3, 20], [4, 20]];
I want to combine these two into a new array:
var c = [[1, 10, 20], [2, 10], [3, 10, 20], [4, 10, 20], [5, 10]];
What's the best way to go about doing this. I'll update my question in a second with what I've tried to do.
var c = [];
for(var i = 0; i < a.length; i++) {
for(var j = 0; j < b.length; j++) {
if(a[i][0] == b[j][0]) {
// Push b value into a
a[i][0].push(b[j][1]);
} else {
// Don't do anything...
}
}
}
c = a; // Useless code here but just wanted to return c
return c;
Example
var a = [[1, 10], [2, 10], [3, 10], [4, 10], [5, 10]];
var b = [[1, 20], [3, 20], [4, 20]];
var c = [];
// Loop over a
for (var n = 0; n < a.length; n++) {
// Create copy of a's value
var subA = a[n].slice(0);
// Loop over b
for (var i = 0; i < b.length; i++) {
var subB = b[i];
// Check if a contains b
if (subA.indexOf(subB[0]) === 0) {
// Add b to new a value
subA.push(subB[1]);
}
}
// Add new value to c
c.push(subA);
}
console.log(a)
console.log(c);
Edit 1: updated for loop
Edit 2: If first item equals first item
Edit 3: Slice a to retain original values
Why don't you use plain arrays? They can be sparse.
var a = [10, 10, 10, 10, 10];
var b = [20, , 20, 20];
Now get them into one array:
var c = new Array(Math.max(a.length, b.length));
for (var i=0; i<c.length; i++)
if (i in a && i in b)
c[i] = [a[i], b[i]];
else if (i in a)
c[i] = [a[i]];
else if (i in b)
c[i] = [b[i]];
For the case that your objects (the items really don't have to be arrays) consist of a non-integer indexing values, you might use a simple standard merge algorithm on the two sorted lists. It will run in O(n+m), not in O(n*m) as your solution. See this answer for an example implementation and further pointers.
Related
I was trying to do a code Where i need use a bidimensional array and when i get it the index it say the variable isn't asigned
let vertices = [
[1, 10],
[2, 20],
[3, 30],
[1, 10],
];
for (let i = 0; i < vertices.length; i++) {
console.log(vertices[i][1]);
console.log(vertices[i + 1][0]);
}
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.
I'm creating a tictactoe game and I'm trying to compare each set array within the winPattern 2d array to the placePieces array.
I've created loops to iterate through the winPattern 2d array for each placePieces array but because it doesn't recognize each array as a set and simply iterates through individual values, it doesn't work as intended.
const winPattern = [
//horizontal
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
//vertical
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
//diagonal
[0, 4, 8],
[2, 4, 6]
];
//positions that o or x would be in tictactoe
const placePieces = [0, 1, 2, 4, 8];
let count = 0;
nextPiece:
for (let i = 0; i < placePieces.length; i++) {
for (let j = 0; j < winPattern.length; j++) {
for (let n = 0; n < winPattern[0].length; n++) {
if (placePieces[i] === winPattern[j][n]) {
//Prints out the matches and mismatches
console.log(`It matches: Piece: ${placePieces[i]} //\\ Pattern: ${winPattern[j][n]}`);
continue nextPiece;
} else {
console.log(`It doesn't match: Piece: ${placePieces[i]} //\\Pattern: ${winPattern[j][n]}`);
}
}
}
}
I'm expecting the placePieces array to compare values with each SET of arrays in the winPattern 2d array.
This code should work to see if the users current array matches anything in the answers array -
var winPattern = [
//horizontal
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
//vertical
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
//diagonal
[0, 4, 8],
[2, 4, 6]
];
//positions that o or x would be in tictactoe
var placePieces = [0, 1, 2, 4, 8, ];
var count = 0;
function arraysEqual(a, b) {
if (a === b) return true;
if (a == null || b == null) return false;
if (a.length != b.length) return false;
for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false;
}
return true;
}
function checkMatch(arr){
for(var i = 0; i < winPattern.length; i++){
for(var j = 0; j < arr.length - 2; j++){
for(var k = j + 1; k < arr.length - 1; k++){
for(var l = k + 1; l < arr.length; l++){
var possibleAnswer = [arr[j], arr[k], arr[l]];
if(arraysEqual(possibleAnswer, winPattern[i])) return true;
}
}
}
}
return false;
}
This is assuming placePieces is sorted because it seemed like it was in your example. Hope this helps!
I want to see the output like
[0, 1, 2]
[3, 4, 5, 6]
[7, 8, 9]
[10, 11, 12, 13]
[14, 15, 16]
...
recognize every three(a cycle) and four(b cycle) to do something.
I have only figure out some bad way I think like following:
var arr = [];
function a(n) {
var eachCycle = 7;
var aCycle = 3;
var bCycle = 0;
arr.push(0);
for (var i = 1; i < n; i += 1) {
if (i % eachCycle === aCycle || i % eachCycle === bCycle) {
if(i % eachCycle === aCycle) {
// print three column
} else if(i % eachCycle === bCycle) {
// print four column
}
console.log(arr);
arr.length = 0;
}
arr.push(i)
}
}
is there any good idea to improve this function for the output !?
Thanks
How about this:
function a(n)
{
// keep track of all the cycles
var total = [];
// hold values for the current cycle
var temp = [];
// cycle sizes
var cycleSizes = [3, 4];
// index of the current cycle
var currentCycleIndex = 0;
// iterate through numbers
for(var i = 0; i < n; ++i)
{
// push the value into the temp
temp.push(i);
// if the length of the temp array is the length we want for the current cycle then
if(temp.length == cycleSizes[currentCycleIndex])
{
// save the cycle data
total.push(temp);
// reset the cycle
temp = [];
// change the cycle
currentCycleIndex = currentCycleIndex ^ 1;
}
}
return total;
}
a(9);
[
[0, 1, 2],
[3, 4, 5, 6],
[7, 8]
];
a(17);
[
[0, 1, 2],
[3, 4, 5, 6],
[7, 8, 9],
[10, 11, 12, 13],
[14, 15, 16],
];
I have a function that picks all elements from a 2-dimensional array by its rows and returns a 1-dimensional array.
The array has a variable amount of columns and rows.
Example:
let arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
];
Returns:
[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]
The function i came up with:
convertList = (list) => {
let result = [];
let listTotalEntries = R.sum(R.map(R.length)(list));
let mod = R.modulo(R.__, list.length);
let counterRow = -1;
for (let i = 0; i < listTotalEntries; i++) {
if (mod(i) === 0) {
counterRow++;
}
if (list[mod(i)][counterRow]) {
result.push(list[mod(i)][counterRow]);
console.log(list[mod(i)][counterRow]);
}
}
console.log(result);
return result;
};
Question: This function works only with square matrices - how can i make it work with a variable length of the contained arrays?
Example:
let arr = [
[1, 2],
[],
[9, 10, 11, 12]
];
Should return:
[1, 9, 2, 10, 11, 12]
Thanks for your help!
Muff
You had a ramda.js tag in here. With Ramda, it's pretty simple, since there are two functions that will help:
const convertList = compose(flatten, transpose);
convertList(arr); //=> [1, 9, 2, 10, 11, 12]
transpose flips a matrix over its main diagonal, that is, changing rows to columns and vice versa. flatten turns a list of lists into a plain list. So composeing like this essentially creates the equivalent of list => flatten(transpose(list)).
You can see this in action on the Ramda REPL.
I suggest to go step-by-step through the arrays
var arr1 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],
arr2 = [[1, 2], [], [9, 10, 11, 12]];
function single(array) {
var r = [],
max = Math.max.apply(null, array.map(function (a) { return a.length; })),
i = 0, j,
l = array.length;
while (i < max) {
for (j = 0; j < l ; j++) {
i in array[j] && r.push(array[j][i]);
}
i++;
}
return r;
}
document.write('<pre>' + JSON.stringify(single(arr1), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(single(arr2), 0, 4) + '</pre>');
Did you try this simple one?
var singleDimensionArr = arr.reduce(function(prev,current){return prev.concat(current)});
For example
[
[1, 2],
[],
[9, 10, 11, 12]
].reduce(function(prev,current){return prev.concat(current)});
outputs [1, 2, 9, 10, 11, 12]
Edit:
Based on the inputs from OP below, since the concatenation needs to happen column wise
var max = Math.max.apply(null, arr.map(function (a) { return a.length; }));
var finalArr = []; for( var i = 0; i < max; i++)
{
for( var j = 0; j < arr.length; j++)
{
arr[j][i] ? finalArr.push(arr[j][i]) : "";
}
}
console.log(arr);
This example makes a big sparse array putting each item where it would belong if the array were square. Then it filters out null values which occur where no input item was present.
let arr = [
[1, 2],
[],
[9, 10, 11, 12]
];
var out = arr.reduce(function(o,n,i,a) {
for (var j=0;j<n.length;j++){
o[a.length * j + i] = n[j];
}
return o;
},[]).filter(function(n) {
return n !== null;
});
alert(JSON.stringify(out));