Function that creates an array with subarries - javascript

I have a function which creates an array of subarrays. It takes three parameters: the number of subarries to create within the array (numSub), the number of times the desired value occurs within each subarray (numValue), and the desired value (value).
For example, if I were to call the function with (3, 2, test), I would want the following output:
Array [Array ["test", "test"], Array ["test", "test"], Array ["test", "test"]]
Here is the function I have written:
function subarrs(numSub, numValue, value) {
let arr = [];
for (let i = 0; i < numSub; i++) {
arr.push([]);
}
arr.forEach(function(sub) {
sub.fill(value, 0, numValue - 1);
});
return arr;
}
console.log(subarrs(3, 2, 'test'));
I have looped through the numSub variable and inserted an array into arr for each iteration. This was successful. (Array [Array [], Array [], Array []])
I then use a forEach loop to fill each sub-array with value beginning at index 0 and ending at index numValue - 1 (because the second occurrence of the value would actually be at index 1.)
The function does not work as intended, however. Rather than the aforementioned desired output, I receive this:
Array [Array [], Array [], Array []]

You can use fill on an array that has received the right length, like Array(numValue).fill(numValue). Here is how you could do it:
function subarrs(numSub, numValue, value) {
return Array.from({length: numSub}, () => Array(numValue).fill(value));
}
console.log(subarrs(3, 2, 'test'));

You are filling an empty array. It's still an empty array (nothing to fill).
You should construct the array of some length:
arr.push(new Array(numValue));
Complete:
function subarrs(numSub, numValue, value) {
let arr = [];
for (let i = 0; i < numSub; i++) {
arr.push(new Array(numValue));
}
arr.forEach(function(sub) {
sub.fill(value);
});
return arr;
}
console.log(subarrs(3, 2, 'test'));

Array.fill() only modifies array values. It does not add new ones. Use push again instead
function subarrs(numSub, numValue, value) {
let arr = [];
for (let i = 0; i < numSub; i++) {
arr.push([]);
}
arr.forEach(function(sub) {
for (let j = 0; j < numValue; j++) {
sub.push(value);
}
});
return arr;
}
console.log(subarrs(3, 2, 'test'));

You can use .push method to add value into your array instead .fill, see working demo :
function subarrs(numSub, numValue, value) {
let arr = [];
for (let i = 0; i < numSub; i++) {
arr.push([]);
for (let j = 0; j < numValue; j++) {
arr[i].push(value);
}
}
return arr;
}
console.log(subarrs(3, 2, 'test'));

fill will only work on indexes that already exist and its second parameter in your case should be the length of the array (which is the default value) and not length - 1. You can see it here:
let myEmptyArray = [];
let myFullArray = [1, 2, 3, 4];
myEmptyArray.fill(0, 0, 4);
myFullArray.fill(0, 0, 4);
console.log(myEmptyArray, myFullArray)
You could push an Array with the necessary slots already in place with new Array(numValue). Something like this:
function subarrs(numSub, numValue, value) {
let arr = [];
for (let i = 0; i < numSub; i++) {
arr.push(new Array(numValue));
}
arr.forEach(function(sub) {
sub.fill(value);
});
return arr;
}
console.log(subarrs(3, 2, 'test'));

If you have es2015+ You can do it easily :
const subarrs = (length, subLength, value) =>
[...Array(length)].map(() => [...Array(subLength)].fill(value));
subarrs(3, 2, 'test');
(Edited) after the first comment

Related

How to get index of array elements by looping through

I'm trying to get indices of array elements. I'm going to use it for Leetcode question "Create Target Array in the Given Order".
Right now I wrote the following code but it doesn't work. (returns undefined)
var createTargetArray = function(nums) {
for(var i=0; i<nums.length; i++) {
console.log(nums.indexOf[i])
}
};
const num = [1,2,3,4,0,108];
createTargetArray(num);
Expected output from that code: [0, 1, 2, 3, 4, 5]
Am I using indexOf method incorrectly?
To get the index of the numbers, you have to call indexOf as a function call (indexOf(i))and not an array accessor (indexOf[i])
Try running the snippet below to check.
var createTargetArray = function(nums) {
for(var i=0; i<nums.length; i++) {
console.log(nums.indexOf(i))
}
};
const num = [1,2,3,4,0,108];
createTargetArray(num);
And if you want the index of exery number, that's just your variable i. You don't need to call the indexOf method.
var createTargetArray = function(nums) {
for(var i=0; i<nums.length; i++) {
console.log(i)
}
};
const num = [1,2,3,4,0,108];
createTargetArray(num);
var createTargetArray = function(nums) {
for(var i=0; i<nums.length; i++) {
console.log(nums.indexOf[i]) // <--mistake
}
};
indexOf is a method
console.log(nums.indexOf(nums[i]));
But since you are looping through the array sequentially output will always be [0, 1, 2, ... n]

Insert value multiple times into array based on argument passed

I have a array like this:
var oldArr = [2,3,4,2,3,5,6,4,2,3,2];
var newArr = [];
I am passing a argument(number) to a function which should insert values from oldArr into newArr taking the argument as length for each element found in old array.
function getNumbers(num){
console.log('value passed is ', num);
for(var i=0; i<arr.length;i++){
newArr.push(arr[i]);
}
console.log('newArr', newArr);
}
getNumbers(2);
For example,
if I pass number 2 as in getNumbers(2);
new array output should be:
[2,2,3,3,4,4,5,5,6,6] //as the argument/length passed is 2.
if I pass number 3 as in getNumbers(3);
[2,2,2,3,3,3,4,4,4,5,5,5,6,6,6] //as the argument/length passed is 3.
How do I achieve this?
Try this
var oldArr = [2,3,4,2,3,5,6,4,2,3,2];
function getNumbers(arr, num){
return Array.from(new Set(arr))
.map((e) => new Array(num).fill().map(v => e))
.reduce((a, b) => a.concat(b),[]);
}
console.log(getNumbers(oldArr, 2));
console.log(getNumbers(oldArr, 3));
First of all, you need to get the unique values from the array. That's the Array.from(new Set(arr));.
Secondly, we can allocate new array for each number (to be able to nicely flatten it later). That's what new Array(num).fill().map(v => e)) does. Result of this will be like [[2,2],[3,3],[4,4]..] etc.
And lastly, flatten it all using Array.prototype.reduce.
var oldArr = [2,3,4,2,3,5,6,4,2,3,2];
var uniqueArr = oldArr.filter(function(elem, index, self) {
return index == self.indexOf(elem);
})
console.log(uniqueArr)
function getNumbers(num){
var newArr = [];
for(var i=0; i<uniqueArr.length;i++){
for(var j=0;j<num;j++)
newArr.push(uniqueArr[i]);
}
console.log('newArr', newArr);
}
getNumbers(2);
getNumbers(3);
Remove all your duplicates from your old array using Array#Filter , then loop through all element and store it in new array.
The following function should work
function duplicateN(oldArray, newArray, N) {
for (var i = 0; i < oldArray.length; i++) {
for (var j = 0; j < N; j++) {
newArray.push(oldArray[i]);
}
}
}
It simply iterates over each value in the original array and then inserts it N times.
I'm not sure the usage of this, but if newArray is always empty, something like this would be more maintainable
function duplicateN(inputArray, N) {
var duplicatedArray = [];
for (var i = 0; i < inputArray.length; i++) {
for (var j = 0; j < N; j++) {
duplicatedArray.push(inputArray[i]);
}
}
return duplicatedArray;
}
var arr = [2,3,4,5];
function getNumbers(num){
var j = 1;
var newArr = [];
for(var i=0; i<arr.length;i++)
{
j = 1;
while(j<=num){
newArr.push(arr[i]);
j++;
}
}
console.log(newArr.join());
}
getNumbers(4);
let multiply_array = (arr, mi = 1) =>
[].concat.apply([], arr.filter((i, ind) =>
arr.indexOf(i) == ind).map(i =>
Array(mi).fill(i)));
The multiply_array function takes two parameters, an array and the multiplying integer. It filters through the array and finds all unique values by comparing position. It then maps over all the remaining unique integers and replaces them with an array that is the length specified by the passed in multiplying integer, and filled with the unique value. All of it is concatenated together to form one array.
var oldArr = [2, 3, 4, 2, 3, 5, 6, 4, 2, 3, 2];
var newArr = [];
let multiply_array = (arr, mi = 1) =>
[].concat.apply([], arr.filter((i, ind) =>
arr.indexOf(i) == ind).map(i =>
Array(mi).fill(i)));
console.log(multiply_array(oldArr, 3));
You can do this using chain of Array.prototype methods:
var oldArr = [2,3,4,2,3,5,6,4,2,3,2];
function getNumbers(num){
return oldArr
.filter((elem, index, arr) => !arr.slice(index + 1).includes(elem))
.sort((prev, next) => next < prev)
.reduce((result, elem) => result.concat(Array(num).fill(elem)), [])
}
console.log(getNumbers(2));
console.log(getNumbers(3));

compare elements of array of many arrays

I trying to loop through an array of arrays, and compare the elements with each-other in-order to find the common elements. so lets say if we have var arr = [[1,2,3],[4,2,5]]; I want to first compare [i][i] and [i+1][i], [i][i+1] and [i+1][i+1] and [i][i+2] and [i+1][i+2] and so on. here is my code:
function sym(args) {
var fullArr = [];
var finalArr = [];
// store the arguments inside a single array
for (var count = 0; count < arguments.length; count ++) {
fullArr[count] = arguments[count];
}
// loop through finalArr[];
for (var i = 0; i < fullArr.length; i++) {
if (fullArr[i][i] == fullArr[i++][i++]) {
// if the element matches (it is a common element)
// store it inside finalArr
finalArr[i] = fullArr[i];
}
}
return finalArr;
}
sym([1, 2, 3], [5, 2, 1, 4]);
problem: when I run the code instead of an array containing the matching element, I get an empty array
You first have to iterate over one array and see if the other array includes the value you have specified.
My answer is similar to a nested for loop in that the includes method does exactly that. It takes in as a parameter an element and checks if the array which called it contains said element. In order to do that it must iterate through all elements in the array in the worst case.
My answer also assumes that you only want to count duplicate matches once.
function sym(args) {
var fullArr = [];
var finalArr = [];
// store the arguments inside a single array
for (var count = 0; count < arguments.length; count ++) {
fullArr[count] = arguments[count];
}
// loop through finalArr[];
//since you are comparing only two arrays in this
//example you just have to iterate over each element in the first array aka fullArr[0] and
//check if each element "e" is also in the second array aka fullArr[1]
//AND that your final output array does not already contain it.
//If both of these are true then we push the element to the output array.
fullArr[0].forEach(function(e){
if(fullArr[1].includes(e) && !finalArr.includes(e)) finalArr.push(e);
});
return finalArr;
}
sym([1, 2, 3], [5, 2, 1, 4]);
However if you want to check if a particular element exists in all collections of an n length array then I would propose something like this:
function sym(args) {
var fullArr = [];
var finalArr = [];
// store the arguments inside a single array
for (var count = 0; count < arguments.length; count ++) {
fullArr[count] = arguments[count];
}
var newArr = fullArr[0].reduce( function(prev, e1) {
if(prev.indexOf(e1) < 0 && fullArr.every( function(arr){
return arr.indexOf(e1) > -1;
})){
return [...prev, e1];
}else{
return prev;
};
},[]);
alert(newArr);
return newArr;
}
sym([1,1, 2, 3,4], [5, 2, 1, 4], [4,1,2, 5]);
You can iterate over the first array and check if any of its values are common through all the other arrays.
function sym() {
var common = [];
for (var i=0; i<arguments[0].length; i++) {
var isCommon = common.indexOf(arguments[0][i]) === -1; // first check if its not already exists in the common array
for (var j=1; j<arguments.length && isCommon; j++) {
isCommon = arguments[j].indexOf(arguments[0][i]) > -1
}
if (isCommon) common.push(arguments[0][i])
}
return common;
}
of course you can improve it by iterating over the smallest array.
In your code, when the following line executes, you also increment the value of i which is your control variable:
if (fullArr[i][i] == fullArr[i++][i++])
Thus, this is how your i variable gets incremented in each iteration:
Iteration #1: i = 0
Iteration #2: i = 3
- you get i+2 from the line that I mentioned above, +1 more from the increment that you specify in the final condition of the for loop
Therefore, even after the first iteration, your function will return an empty array on your particular scenario, as you are passing an array of length 3, and the for loop ends after i = 0 on the first iteration.
Even if the loop would go on, it would return an index out of bounds exception because your array of length 3 would not have an array[3] element.
For example, if you want to compare just two arrays, as in your scenario, you need to loop through each of them and compare their elements:
function sym(array1, array2) {
var results = [];
for (var i = 0; i < array1.length; i++) {
for (var j = 0; j < array2.length; j++) {
if(array1[i] === array2[j]) {
if(results.indexOf(array1[i]) === -1) {
results.push(array1[i]);
}
}
}
}
return results;
}
sym([1, 2, 3], [5, 2, 1, 4]);
I have also built a solution that returns the intersection of the arrays that you provide as the parameters for the function, regardless of how many arrays there are:
function sym(args) {
var paramSet = Array.prototype.slice.call(arguments);
var counterObject = {};
var results = [];
paramSet.forEach(function (array) {
// Filter the arrays in order to remove duplicate values
var uniqueArray = array.filter(function (elem, index, arr) {
return index == arr.indexOf(elem);
});
uniqueArray.forEach(function (element) {
if (Object.prototype.hasOwnProperty.call(counterObject, element)) {
counterObject[element]++;
} else {
counterObject[element] = 1;
}
});
});
for (var key in counterObject) {
if (counterObject[key] === paramSet.length) {
results.push(parseInt(key));
}
}
return results;
}
sym([1, 2, 3, 3, 3], [5, 2, 1, 4], [1, 7, 9, 10]);
The above code will return [1] for the example that I provided, as that is the intersection of all 3 arrays.

Understanding For loops in javascript - printing index of values in Array

I'm trying to print the indexes of values of an array. When I do this:
let a = [1,2,3,4,5];
var findIdx = function (arr) {
for (let i = 0 ; i < arr.length; i++) {
var indexes = [];
var index = arr[i];
console.log(index);
return indexes.push(index);
}
return indexes;
}
console.log(findIdx(a));
// => 0,1 // return
Which is not what I want, I would like to get the index of those values. Furthermore, my return is returning 1. I would like an array made of those indexes. What am I missing?
When I do a for in loop I get what I want on my console, but I'm still returning the value where that index is found.
let a = [1,2,3,4,5];
var findIdxWithForIn = function (arr) {
var indexes = [];
for (i in arr) {
var index = i;
console.log(index);
return indexes.push(index);
}
return indexes
}
console.log(findIdxWithForIn(a));
// => 0, 1 // return
TL;DR: Here is a jsfiddle with the above code.
Note that I would like just to all the indexes inside that array
You are printing var index which is not an index it is element in array:
var index = arr[i];
console.log(index);
You need to get index so var index = i;. Because i in for loop is actual index. You can also use arr.indexOf(...); to get index of specific element.
You should do something like this,
var findIdxWithForIn = function (arr) {
var indexes = [];
for (i in arr) {
var index = i;
indexes.push(index)
console.log(index);
}
return indexes;
}
Now in case you want to find out what the indexes array contains then again you have put that in a for loop and extract
indexes.push(index) Should be inside for loop. You were doing it wrong.
var findIdxWithForIn = function (arr) {
var indexes = [];
for (i in arr) {
var index = i;
indexes.push(index)
}
return indexes;
}
console.log(findIdxWithForIn(a));
Try this out
let a = [1, 2, 3, 4, 5];
console.log('======= For Loop ========')
/*
For loop
*/
var findIdx = function (arr) {
var indexes = [];
for (let i = 0 ; i < arr.length; i++) {
var index = arr[i];
console.log(index);
indexes.push(index);
}
return indexes
}
console.log(findIdx(a));
console.log('======= For In ========')
/*
For In Loop
*/
var findIdxWithForIn = function (arr) {
var indexes = [];
for (i in arr) {
var index = i;
console.log(index);
indexes.push(index);
}
return indexes //.push(index);
}
console.log(findIdxWithForIn(a));

push to object if not exists from params

I've been trying and searching how to loop through the params to check if those already exist in an array, i haven't got it fully working but when there is a duplicate value it dose not return at all.
The idear is pass multiple values is param then loop through those vals and only push if it dose not exist in the array.
var arr = [7,3,1];
function pushNew(obj) {
var prams = obj;
for(var k = 0; k < obj.length; k++){
for (var i = 0; i < arr.length; i++) {
if (arr[i] == prams[k]) {
return;
}
}
array.push(prams[k]);
}
// console.info(arr);
}
pushNew([2,7,4]);
A short and more modern way to just get all the unique values is to use Array.from with Set. A Set is an array-like structure that will only hold unique values. Array.from converts an array-like structure into a real array.
In your case, you can just concat both arrays, pass them to Set to remove the duplicates, and use Array.from to convert it back to a regular array.
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [3, 4, 5, 6, 7];
var result = Array.from(new Set(arr1.concat(arr2)));
document.write(JSON.stringify(result));
Actually, your existing code nearly works.
You can set a flag if you find a match in the inner loop and instead of return you should use break to escape the loop. Then use push after the inner loop if a match wasn't found. Also, there is no need for both obj and prams (which I've renamed to params), so:
var arr = [7,3,1];
function pushNew(params) {
var found;
for(var k=0; k<params.length; k++){
// Set found to initial value on each outer loop
found = false;
for (var i=0; i<arr.length; i++) {
// If find match, set flag and break from loop (for efficiency)
if (arr[i] == params[k]) {
found = true;
break;
}
}
// If match not found, push into arr
if (!found) arr.push(params[k]);
}
}
pushNew([7,2])
document.write(arr); // 7,3,1,2
If you want efficient code, consider creating an index and using in:
var arr = [7,3,1];
function addParams(params) {
var index = arr.reduce(function(acc, v) {
acc[v] = true;
return acc;
},{});
params.forEach(function(v) {
if (!(v in index)) arr.push(v);
});
}
addParams([7,3,2]);
document.write(arr);
You can use indexOf to validate if element is present in an array. forEach is another array method which works like loop.
var arr = [7,3,1];
function pushNew(obj) {
//var prams = obj;
obj.forEach(function(item){ // iterate through each element
if(arr.indexOf(item) == -1){ //indexOf return -1 is element is not present in an array
arr.push(item)
}
})
console.log(arr);
}
pushNew([2,7,4]);
Working Jsfiddle
var arr = [7, 3, 1];
function pushNew(obj) {
for (var k = 0; k < obj.length; k++) {
if (arr.indexOf(obj[k]) == -1) {
arr.push(obj[k]);
}
}
}
pushNew([2, 7, 4]);
You can use _.union function of lodash.
_.union([2, 1], [4, 2], [1, 2]);
// → [2, 1, 4]

Categories