How to join two arrays into one two-dimensional array? - javascript

I have two arrays. How can I join them into one multidimensional array?
The first array is:
var arrayA = ['Jhon, kend, 12, 62626262662',
'Lisa, Ann, 43, 672536452',
'Sophie, Lynn, 23, 636366363'];
My other array has the values:
var arrayB = ['Jhon', 'Lisa', 'Sophie'];
How could I get an array with this format??
var jarray = [['Jhon', ['Jhon, kend, 12, 62626262662']],
['Lisa', ['Lisa, Ann, 43, 672536452']],
['Sohphie', ['Sophie, Lynn, 23, 636366363']]]

var jarray = [];
for (var i=0; i<arrayA.length && i<arrayB.length; i++)
jarray[i] = [arrayB[i], [arrayA[i]]];
However, I wouldn't call that "multidimensional array" - that usually refers to arrays that include items of the same type. Also I'm not sure why you want the second part of your arrays be an one-element array.

Here is a map version
const arrayA = ['Jhon, kend, 12, 62626262662',
'Lisa, Ann, 43, 672536452',
'Sophie, Lynn, 23, 636366363'];
const arrayB = ['Jhon', 'Lisa', 'Sophie'];
/* expected output
var jarray = [['Jhon', ['Jhon, kend, 12, 62626262662']],
['Lisa', ['Lisa, Ann, 43, 672536452']],
['Sohphie', ['Sophie, Lynn, 23, 636366363']]] */
const jarray = arrayB.map((item,i) => [item,[arrayA[i]]]);
console.log(jarray);

You can use Underscore.js http://underscorejs.org/#find
Looks through each value in the list, returning the first one that passes a truth test (iterator). The function returns as soon as it finds an acceptable element, and doesn't traverse the entire list.
var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> 2
Then, you can make the same with the array B elements and by code, make a join.

This is what I did to get what you were asking:
var jarray = [];
for (var i = 0; i < arrayB.length; i++) {
jarray[i] = [];
jarray[i].push(arrayB[i]);
var valuesList = [],
comparator = new RegExp(arrayB[i]);
for (var e = 0; e < arrayA.length; e++) {
if (comparator.test(arrayA[e])) {
valuesList.push(arrayA[e]);
}
}
jarray[i].push(valuesList);
}

Related

How can I store numbers in arrays?

I built a program that check if there are two common numbers in two different arrays, and then log those numbers. I was able to do that using a simple for loop that goes trough each element of the first array and check if there is an equal element in the second array. Each of the same element in the arrays are stored in a third array called "commonNumbers" which I logged at the end of the program.
const firstNumbers = [12, 45, 6, 78]
const secondNumbers = [6, 7, 12, 45]
let commonNumbers = []
for (let i = 0; i < firstNumbers.length; i++) {
for (let j = 0; j < secondNumbers.length; j++) {
if (firstNumbers[i] === secondNumbers[j]) {
commonNumbers += secondNumbers[j]
}
} }
console.log(commonNumbers)
The result for this example is the seguent:
12456
[Finished in 0.2s]
My question is about the result. I can see that the program actually worked and logged the same element in the arrays (12, 45, 6), but I can't figure out why "commonNumbers" stored the result in such a way that there are no spaces between the numbers.
I would like to clearly see each number.
For example if I call the first element of "commonNumbers" (of index 0):
commonNumbers[0] the result I will get is not going to be "12" as expected, but "1".
Same thing happen if I say: commonNumbers[2] the result is going to be "4", not "6".
Apparently "commonNumbers" array stored the element in a different way I was expecting. How can I solve this, using this "storing" method?
This is because +=, on your array, implicitly convert it to a string, as you can see in the example below, where a Number is summed to an Array.
console.log(typeof([] + 1));
Just use the comfortable .push (read more about push here) method of arrays in order to add the element:
const firstNumbers = [12, 45, 6, 78]
const secondNumbers = [6, 7, 12, 45]
let commonNumbers = []
for (let i = 0; i < firstNumbers.length; i++) {
for (let j = 0; j < secondNumbers.length; j++) {
if (firstNumbers[i] === secondNumbers[j]) {
commonNumbers.push(secondNumbers[j]);
}
} }
console.log(commonNumbers)
As a (final) side note, there are several other ways to accomplish your task, the cleverest you can probably go with is filter. You may also would take care of eventual duplicates, since if your input array has two identical numbers the commonsNumber result will contain both, which might be unintended.
The "definitive" clever solution that tries to also take care of duplicates and to loop the shorter array would be something like this:
// Inputs with duplicates, and longer array on second case.
const firstNumbers = [12, 45, 6, 78, 12, 12, 6, 45];
const secondNumbers = [6, 7, 12, 45, 45, 45, 12, 6, 99, 19, 5912, 9419, 1, 4, 8, 6, 52, 45];
// Performance: look for duplicates starting from the shortest array. Also, make a set to remove duplicate items.
const [shortestArray, longestArray] = firstNumbers.length < secondNumbers.length ? [firstNumbers, secondNumbers] : [secondNumbers, firstNumbers];
// Remove duplicates.
const dedupes = [...new Set(shortestArray)];
// Find commomn items using filter.
const commons = dedupes.filter(i => longestArray.indexOf(i) > -1);
console.log('commons is', commons);
Don't get me wrong, the solution is fine, just wanted to add "something" to the boilerplate, to take care of eventual additional scenarios.
const firstNumbers = [12, 45, 6, 78]
const secondNumbers = [6, 7, 12, 45]
let commonNumbers = []
for (let i = 0; i < firstNumbers.length; i++) {
for (let j = 0; j < secondNumbers.length; j++) {
if (firstNumbers[i] === secondNumbers[j]) {
commonNumbers.push(secondNumbers[j])
}
} }
The push method appends values to an array.
You seem to be looking for array.prototype.push (mdn). E.g.:
const firstNumbers = [12, 45, 6, 78]
const secondNumbers = [6, 7, 12, 45]
let commonNumbers = []
for (let i = 0; i < firstNumbers.length; i++)
for (let j = 0; j < secondNumbers.length; j++)
if (firstNumbers[i] === secondNumbers[j])
commonNumbers.push(secondNumbers[j]);
console.log(commonNumbers); // as an array
console.log(commonNumbers.join(', '));
why "commonNumbers" stored the result in such a way that there are no spaces between the numbers.
The + operator will try to cast its operands to compatible types. In this case, that is a string, where empty arrays [] are cast to empty strings '', and numbers 3 are cast to the corresponding string '3'. E.g. [] + 3 is the string '3'.
console.log([], typeof []);
console.log(3, typeof 3);
console.log([] + 3, typeof ([] + 3));

How to split a large array into smaller array based upon given index values,

I have a large array e.g. aa=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
I have another array which holds the indexes values based upon which large array need to be chunked. e.g. cc=[10,16]
I want that array aa to be chunked into new arrays
dd[] = [from 0 to cc[0]index]
ee[] = [from cc[0]index to cc[next value]index]
EXAMPLE
dd[] = [1,2,3,4,5,6,7,8,9,10]
ee[] = [11,12,13,14,15,16]
and so on until cc[] has indexes
I could not figure out the logic, if anyone can help me please.
You could use Array#map and Array#slice for the parts.
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
indices = [10, 16],
result = indices.map(function (a, i, aa) {
return array.slice(aa[i - 1] || 0, a);
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
you can use the new and simple array.slice:
var array=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
var i,j,temparray,chunk = 10;
for (i=0,j=array.length; i<j; i+=chunk) {
temparray = array.slice(i,i+chunk);
console.info(temparray);
}
You can do something like this if you don't wanna use build in methods.
function createChunks(aa, cc) {
var temp = [], chunks = [];
for(var i=0, j=0, k=0; i<aa.length; i++) {
if(aa[i] == cc[j]) {
temp[k] = aa[i];
chunks.push(temp);
temp = []; k=0; j++;
}
else
temp[k++] = aa[i];
}
return chunks;
}
var aa=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], cc=[10, 16];
var chunks = createChunks(aa, cc);
console.log(JSON.stringify(chunks));

Checking whether certain item is in certain array using javascript

I have 10 different arrays. Each array has different numbers.
array1 = [1,2,3,4,5]
array2 = [6,7,8,9,10]
...
array 10 = [51,52,53,54]
let's say I pass in 7. Then I want to know which array it is from and want to return array number. So in this case it is going to be 2.
Should I write a switch statement for each array? Appreciate it in javascript.
try:
var arrays = [array1, array2, ..., array10];
for(var i=0; i<arrays.length; ++i) {
if (arrays[i].indexOf(value) != -1) {
console.log('found in array' + (i+1));
}
}
You cannot directly retrieve the name of array.The reason is this variable is only storing a reference to the object.
Instead you can have a key inside the same array which represent its name. Then indexOf can be used to find the array which contain the number , & if it is so, then get the array name
var array1 = [1,2,3,4,5];
array1.name ="array1";
var array2 = [6,7,8,9,10];
array2.name ="array2";
var array10 = [51,52,53,54]
array10.name ="array10";
var parArray = [array1,array2,array10]
function _getArrayName(number){
for(var o=0;o<parArray.length;o++){
var _tem = parArray[o];
if(parArray[o].indexOf(number) !==-1){
console.log(parArray[o].name);
}
}
}
_getArrayName(6) //prints array2
jsfiddle
One fast method should be using hash tables or as i would like to call LUT. Accordingly this job boils down to a single liner as follows;
var arrs = {
arr1 : [1,2,3,4,5],
arr2 : [6,7,8,9,10],
arr3 : [12,14,16,17],
arr4 : [21,23,24,25,27,20],
arr5 : [31,34,35,39],
arr6 : [45,46,44],
arr7 : [58,59],
arr8 : [66,67,69,61],
arr9 : [72,73,75,79,71],
arr0 : [81,85,98,99,90,80]
},
lut = Object.keys(arrs).reduce((p,c) => {arrs[c].forEach(n => p[n]=c); return p},{}),
findar = n => lut[n];
document.write("<pre>" + findar(12) + "</pre>");
One way to do this is have the arrays in an object and iterate over the keys/values. This method doesn't presume the arrays (and therefore their names) are in sequential order.
Note: this will always return a the first match from the function and terminate the search.
var obj = {
array1: [1, 2, 3, 4, 5],
array2: [6, 7, 8, 9, 10],
array3: [51, 52, 53, 54],
array4: [51, 52, 53, 54, 7]
}
function finder(obj, test) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
return key.match(/\d+/)[0];
}
}
return false;
}
finder(obj, 7); // '2'
DEMO
If you want to find all instances of a value in all arrays the function needs to be altered slightly.
function finder(obj, test) {
var keys = Object.keys(obj);
var out = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
out.push(key.match(/\d+/)[0]);
}
}
return out;
}
finder(obj, 7); // ['2', '4']
DEMO

How to merge two different arrays in Javascript?

I have this array,
var arr1 = [19, 1, 1, 1, 1];
and another array,
var arr2 = ["Default", "Dynamic", "Assessment", "Risk", "Privacy"];
What I would like is to merge them somehow such that it would look something like this,
var merged_array = [ ["Default", 19], ["Dynamic", 1], ["Assessment", 1], ["Risk", 3], ["Privacy", 2] ];
how would I do that? I tried join but I did not achieve what I wanted. Thanks in advance!
Using a for loop:
var merged_array = new Array(arr1.length);
for (var i = 0; i < arr1.length; i++) {
merged_array[i] = new Array(arr2[i], arr1[i]);
}
This assumes arr1 and arr2 have the same length.
If you have jquery or equivalent:
var merged_array = $.map(arr1, function(e, i) {
return [arr2[i], e];
});
If not, then just use a for loop, same idea.
var merged_array = []
for (var i = 0; i < arr1.length && i < arr2.length; i++) {
merged_array[i] = [arr2[i], arr1[i]];
}
var result = new Array();
for (var i=0; i<arr1 .length && i<arr2.length ; i++) {
result[i] = new Array();
result[i][0] = arr1[i];
result[i][1] = arr2[i];
}
I'd probably extend the array object especially if this is a common task. Something like this:
Array.prototype.myMerge = function(arr){
var returnArr = [];
for(var i = 0, len = this.length; i < len; i++){
returnArr[i] = [this[i], arr[i]];
}
return returnArr;
};
then you could call it like this:
var merged_array = arr1.myMerge(arr2)
Of course you'd have to add some error checking on the length of the arrays, this function assumes that arr1 is longer or the same length as arr2. But that depends on what you want to do if arr1 and arr2 are different lengths, your question seems to assume they are the same length.
If you include the library underscore.js (prototype.js also has something similar), you can use _.zip(array1,array2). They provide example usage with 3 arrays.
From http://underscorejs.org/#zip :
zip_.zip(*arrays)
Merges together the values of each of the arrays with the values at the corresponding position. Useful when you have separate data sources that are coordinated through matching array indexes. If you're working with a matrix of nested arrays, zip.apply can transpose the matrix in a similar fashion.
_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]

making sure my array of random values doesn't contain duplicate values

I was wondering if anyone can advise how I can make sure the random array I'm generating from another array doesn't contain duplicate values, want to make sure that arr2 contains unique values?
JS
var limit = 5,
i = 0,
arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
arr2 = [];
for ( i; i < limit; i++ ){
var rand = Math.floor((Math.random()*9)+1);
arr2.push( arr1[rand] );
}
console.log(arr2);
Maybe an if statement that compares arr1[rand] with arr2[i] ?
Create a temporary array that is a copy of arr1 containing only unique values:
// Copy unique values in arr1 into temp_arr
var temp_obj = {}, temp_arr = [], i;
for(i = arr1.length; i--;)
temp_obj[arr1[i]] = 1;
for(i in temp_obj)
temp_arr.push(i);
Then you can remove the element from temp_arr each time you add it to arr2. Since we used object keys when copying we have strings, so we can use + to convert them back to numbers when pushing into arr2:
arr2.push(+temp_arr.splice(rand, 1)[0]);
You should also change how you pick random numbers to:
var rand = Math.floor(Math.random()*temp_arr.length);
Whole code:
var limit = 5,
arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
arr2 = [],
rand,
temp_obj = {},
temp_arr = []
i;
// Copy unique values from arr1 into temp_arr
for(i = arr1.length; i--;)
temp_obj[arr1[i]] = 1;
for(i in temp_obj)
temp_arr.push(i);;
// Move elements one at a time from temp_arr to arr2 until limit is reached
for (var i = limit; i--;){
rand = Math.floor(Math.random()*temp_arr.length);
arr2.push(+temp_arr.splice(rand, 1)[0]);
}
console.log(arr2);
The naive O(n^2) solution is to simply check each element and see if any other position in the array has the same value.
A linear time solution can be achieved using a hashset data structure. You can hack one in JavaScript using objects:
var set = {};
set['0'] = true;
set['1'] = true;
if(set.hasOwnProperty('0')) {
alert("duplicate 0!");
}
If the numbers are integers and relatively small, then you can keep track of them in an array of boolean values.
See http://bost.ocks.org/mike/shuffle/ for good info on the Fischer/Yates shuffle. For your problem, you could take the first five elements of the shuffled deck.
try this
for ( i; i < limit; i++ ){
var rand = Math.floor((Math.random()*9)+1);
for(j=0; j < arr1.length; j++)
if(rand == arr1[j]
{
blnfound = true;
break;
}
if(!blnfound)
arr2.push( arr1[rand] );
}
By using jQuery.inArray function :)
var limit = 5,
arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
l = arr1.length,
arr2 = [];
while( limit ){
var tmp = arr1[ Math.random() * l | 0 ];
// for unsigned numbers '|0' construction works like Math.floor
if( !~$.inArray( tmp, arr2 ) ) {
// if not found $.inArray returns -1 ( == ~0 ), then !~-1 == true
limit--;
arr2[ arr2.length ] = tmp;
}
}
console.log( arr2 );

Categories

Resources