function to repeat same numbers y times - javascript

I am trying to write a function that returns the number x. y number of times. The function should be able to take in multiple 2d arrays. There will be only 2 elements per input array.
So for example: function([4,3][2,2][12,5])
//output should be exactly: 444, 22, 1212121212
I have solved most of the problem but I am stuck when x is a 2 digit number.
would appreciate some help in solving this. I must return the solution as a string with a comma (' ,') that separates the different arrays.
Here is my code as of now:
function repeatnumber(data){
var result = " ";
for (var i = 0; i < data.length; i++){
if (Array.isArray(data[i])){
var x = data[i][0]
var y = data[i][1]
for(var j = 1; j <= y; j++){
result = result + x;
}
}
}
var number = result
var answer = number.match(/(\d)\1*/g)
return console.log(answer);
}
repeatnumber([[10, 2][11,1]])// DOESN'T WORK!! output must be: 1010,11
repeatnumber([[1, 2], [2, 3]]) //works
repeatnumber([[1, 4], [3, 6], [9, 2]]) //works

You could check if you got a nested array and map new values and join later all arrays with comma.
function repeatnumber(array) {
return (Array.isArray(array[0]) ? array : [array])
.map(([value, length]) => Array.from({ length }, _ => value).join(''))
.join(', ');
}
console.log(repeatnumber([42, 7]));
console.log(repeatnumber([[10, 2], [11,1]]));
console.log(repeatnumber([[1, 2], [2, 3]]));
console.log(repeatnumber([[1, 4], [3, 6], [9, 2]]));

If you are using es6 this could be the simplest.
let repeatnumber = (inputArr) => {
return inputArr.map((inp) => `${inp[0]}`.repeat(inp[1]));
}

Here's one of the solution.
function repeatNumber(data) {
var results = '';
data.forEach(function(arr) {
for(var i = 0; i< arr[1]; i++) results += arr[0].toString();
results += ',';
})
return results.substring(0, results.length - 1);
}
console.log(repeatNumber([[10, 2], [11,1]]));
console.log(repeatNumber([[1, 2], [2, 3]]));
console.log(repeatNumber([[1, 4], [3, 6], [9, 2]]));

As you've noticed, regex isn't the best option. You're making the question a lot more difficult than it needs to be. You can just make an array of each of those strings and then join them together. Also, more descriptive variable names will go a long way for you.
let data = [[10,2], [11,1]]
function repeatNumber(data) {
let resultArray = []
for (let i=0; i < data.length; i++) {
let num = data[i][0]
let times = data[i][1]
let newString = ""
for (let j=0; j < times; j++) {
newString += num
}
resultArray.push(newString)
}
return resultArray.join(", ")
}
console.log(repeatNumber(data))
If you're ok with a code golf solution, this will accomplish the same task:
data.map(([num, times]) => Array(times).fill(num).join("")).join(", ")

try this :
function repeatnumber(data) {
var result = "";
for (var i = 0; i < data.length; i++)
{
if (Array.isArray(data[i]))
{
var x = data[i][0]
var y = data[i][1]
for(var j = 1; j <= y; j++)
{
{
result = result + x;
}
}
}
if(i != data.length - 1)
result += " ";
}
var number = result
var split = number.split(" ");
//var answer = number.match(/(\d)\1*/g)
return console.log(split);
}
repeatnumber([[10, 2][11,1]]) should be repeatnumber([[10, 2],[11,1]]);

ES6 Solution
const repeat = (arr) => {
arr.map( v => {
const str = new Array(v[1] + 1).join(v[0]);
console.log(str); // save this in array or wherever u want.
})
};
repeat([[1, 4], [3, 6], [9, 2]])

You are missing a comma between two arrays, make it
repeatnumber([[10, 2],[11,1]])
Also, your regex won't work properly when you are adding two digit number, change your logic as
function repeatnumber(data)
{
var answer = [];
for (var i = 0; i < data.length; i++)
{
if (Array.isArray(data[i]))
{
var x = data[i][0]
var y = data[i][1]
result = "";
for(var j = 1; j <= y; j++)
{
result = result + x;
}
answer.push(result)
}
}
return answer;
}
Demo
function repeatnumber(data) {
var answer = [];
for (var i = 0; i < data.length; i++) {
if (Array.isArray(data[i])) {
var x = data[i][0]
var y = data[i][1]
result = "";
for (var j = 1; j <= y; j++) {
result = result + x;
}
answer.push(result)
}
}
return answer;
}
console.log(repeatnumber([
[10, 2],
[11, 1]
])) ;
console.log(repeatnumber([
[1, 2],
[2, 3]
])) ;
console.log(repeatnumber([
[1, 4],
[3, 6],
[9, 2]
])) ;
Edit
Or a more concise method using fill and reduce
function repeatnumber(data)
{
return data.map( s => Array( s[1] ).fill( "" ).reduce( (a,c) => a + s[ 0 ], "" ) )
}
Or using fill and join
function repeatnumber(data)
{
return data.map( s => Array( s[1] + 1 ).fill( "" ).join( s[ 0 ] ) )
}

Small code that works,
// iterate > create array and join with char > join parent array with comma
function repeatnumber(data){
if(!data || data.length < 1) return [];
return data.map(arr => Array(arr[1] + 1).join(arr[0])).join(',');
}
A better approach, thanks to Ariz
function repeatnumber(data) {
if (!data || data.length < 1) return [];
return data.map((arr) => `${arr[0]}`.repeat(arr[1])).join(',');
}
No creation of an extra array, so huge repetitions can be done with ease.

Single pass by nested template literals and .reduce() working hand to hand.
var a = [[10, 2], [11,1]],
b = [[1, 2], [2, 3]],
c = [[1, 4], [3, 6], [9, 2]],
f = a => a.reduce((r,[v,c],i) => `${i ? `${r},`:``}${`${v}`.repeat(c)}`,``);
console.log(f(a));
console.log(f(b));
console.log(f(c));

Related

Is there a best way to find the index value in a two dimensional array

Example:-
1234
2456
5678
I need to find the index of the value 7
Expected output:-
[3,3] // 3rd row and 3rd column.
Note:- Need to consider Time Complexity (ex:-Big(O) notation)
I am not looking for the below like answers
Sample 1
function findInArr(arr, elm) {
var occ = [];
for(var i = 0; i < arr.length; i++)
for(var j = 0; j < arr[i].length; j++)
if (arr[i][j] == elm)
occ.push(i+","+j);
return occ;
}
Test:
var numbers = [[1,2,3,4,5],[6,2,3,5,5],[9,8,3,4,9]];
var x = findInArr(numbers, 4);
console.log("found " + x.length + " occurences: " + x);
Here time complexity is 'n' rows * 'n' columns
Sample 2
var numbers=[[1,2,3,4,5],[6,2,3,5,5],[9,8,3,4,9]];
var searchItem=2;
numbers.forEach(function(parentItem,parentIndex){
parentItem.forEach(function(childItem,childIndex){
if(childItem===searchItem){
console.log(parentIndex);
console.log(childIndex);
}
})
});
this way ?
const numbers = [[1,2,3,4,5],[6,2,3,5,5],[9,8,3,4,9]];
function findInArr(arr, elm) {
let i = arr.findIndex(x=>x.includes(elm))
return (i<0) ? [null,null] : [i,arr[i].indexOf(elm)]
}
console.log( findInArr(numbers, 7))
console.log( findInArr(numbers, 8))
.as-console-wrapper { max-height: 100% !important; top: 0; }
you can use map, also index starts at 0, so your sample above would be [2,2] not [3,3], Below code, will find all indexes for the search item.
var numbers = [
[1, 2, 3, 4, 5],
[6, 2, 3, 5, 5],
[9, 8, 3, 4, 9]
];
var searchItem = 2;
console.log(numbers.map((v, i) => {
var res = v.filter(f => f === searchItem);
if (res.length) {
var ind=v.indexOf(searchItem);
return [i, ind]
}
}).filter(f => f !== undefined));

loop over array, but not every element

I would like to iterate over the array and getting an average from 5 next elements, not from the whole array. I try to do it by code bellow, but it doesn´t work. I appreciate any kind of help or suggestions.
function standardDeviation(array) {
let newArray = [];
for (let i = 0; i < array.length; i++) {
let tempArray = [];
const arrAvg = tempArray =>
tempArray.reduce((a, b) => a + b, 0) / tempArray.length;
newArray += tempArray;
for (let j = array[i]; (j = array[i + 5]); i++) {
tempArray += array[j];
}
}
console.log(newArray);
return newArray;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
standardDeviation(arr);
You could slice a given array and take only five elements for getting an average.
function standardDeviation(array) {
const arrAvg = tempArray => tempArray.reduce((a, b) => a + b, 0) / tempArray.length;
return array.map((_, i, a) => arrAvg(a.slice(i, i + 5)));
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(standardDeviation(arr));
You could try using the slice() function of array element.
// simulated loop index
var curr_index_pos = 3;
// entire array
var array_full = [1,2,3,4,5,6,7,8,9,10];
// array with 5 next values from "curr_index_pos"
var array_5 = array_full.slice(curr_index_pos,curr_index_pos+5);
var sum = 0;
for( var i = 0; i < array_5.length; i++ ) {
sum += parseInt( array_5[i] );
}
var avg = sum/array_5.length;
console.log("array_5", array_5);
// [4,5,6,7,8]
console.log("sum", sum);
// 30
console.log("avg", avg);
// 6

combine two array then calculate it in javascript

I have
var arr1 = [123, 234, 565];
var arr2 = [2, 5, 1];
var arr = arr1.map(function(num, i) {
if(i < arr1.length)
return num + " " + arr2[i];
return num;
});
Then I want to calculate every index in the array:
for (var i=0; i<arr.length; i++) {
arr[i] = parseFloat(arr[i])/100;
}
It just shows the array is [12.3, 23.4, 56.5]. But I want the result to be [12.32, 23.45, 56.51]. Did I do anything wrong?
Try this, you don't need to make multiple passes. You can use a single map to get the value of the other array.
Also, you don't need to check that i is less than the length of the array, it is.
var arr1 = [123, 234, 565];
var arr2 = [2, 5, 1];
result = arr1.map((x, i) => (x + '' + arr2[i]) / 100);
console.log(result);
Try connecting the numbers with a . instead of a space, then dividing by 10 instead of 100 and fixing the number to two decimal places:
var arr1 = [123, 234, 565];
var arr2 = [2, 5, 1];
var arr = arr1.map(function(num, i) {
if(i < arr1.length)
return num + "." + arr2[i];
return num;
});
for (var i=0; i<arr.length; i++) {
arr[i] = (parseFloat(arr[i])/10).toFixed(2);
}
console.log(arr);

find all subarrays in o(n) time 1D array using javascript

I want to collect all subarrays for further computation efficiently in javascript. I'm not sure this is possible, but it seems for a subarray sum kadane's formula is o(n) which is more efficient than other methods. But I'm not sure I how I can store the array at each step.
Similar to this quora question, for me the pseudo code was not enough. Thanks for the further breakdown.
another meta link
an example in action of this for [3, 3, 9, 9, 5]
[3], [9], [5], [9, 5], [9, 3], [9, 9], [3, 3],
[3, 9, 9], [3, 3, 9], [9, 9, 5], [3, 3, 9, 9],
[3, 9, 9, 5], [3, 3, 9, 9, 5]
I had done a work previously to calculate all combinations of amino acids total molecular weight. If you neglect the empty one you should have 2^n - 1 sub arrays. So there is no O(n) here. I've got two methods as binary and recursive.
function getSubArrays(arr){
var len = arr.length,
subs = Array(Math.pow(2,len)).fill();
return subs.map((_,i) => { var j = -1,
k = i,
res = [];
while (++j < len ) {
k & 1 && res.push(arr[j]);
k = k >> 1;
}
return res;
}).slice(1);
}
console.log(JSON.stringify(getSubArrays([1,2,3,4,5])));
function getSubArrays(arr){
if (arr.length === 1) return [arr];
else {
subarr = getSubArrays(arr.slice(1));
return subarr.concat(subarr.map(e => e.concat(arr[0])), [[arr[0]]]);
}
}
console.log(JSON.stringify(getSubArrays([1,2,3,4,5])));
I couldn't manage to get subarrays of an array with more than 23 items though.
Here are the performances. To be on the safe side i try with 22 items, first with recursive and then with binary route.
function getSubArrays(arr){
if (arr.length === 1) return [arr];
else {
subarr = getSubArrays(arr.slice(1));
return subarr.concat(subarr.map(e => e.concat(arr[0])), [[arr[0]]]);
}
}
var aminos = Array(22).fill().map((_,i) => i+1),
subarrs = [],
ps = 0,
pe = 0;
ps = performance.now();
subarrs = getSubArrays(aminos);
pe = performance.now();
console.log("recursive route took: " + (pe-ps) + "msec to produce " + subarrs.length + " sub arrays");
function getSubArrays(arr){
var len = arr.length,
subs = Array(Math.pow(2,len)).fill();
return subs.map((_,i) => { var j = -1,
k = i,
res = [];
while (++j < len ) {
k & 1 && res.push(arr[j]);
k = k >> 1;
}
return res;
}).slice(1);
}
var aminos = Array(22).fill().map((_,i) => i+1),
subarrs = [],
ps = 0,
pe = 0;
ps = performance.now();
subarrs = getSubArrays(aminos);
pe = performance.now();
console.log("binary route took: " + (pe-ps) + "msec to produce " + subarrs.length + " sub arrays");
This is fairly simple to do: https://jsfiddle.net/j1LuvxLq/
All you do is iterate possible lenghts and starting points and just print out the subsets. Complexity is O(n²) where n is the length of the original array. No way to improve it thought because that's the order of how many subsets there are.
var set = [3, 3, 9, 9, 5].join('')
var set_length = set.length
var subsets = []
for (var length_of_subset = 1; length_of_subset <= set_length; length_of_subset++) {
for (var start_of_subset = 0; start_of_subset <= set_length - length_of_subset; start_of_subset++) {
var current_subset = set.substring(start_of_subset, start_of_subset + length_of_subset)
if(subsets.indexOf(current_subset) == -1) {
subsets.push(current_subset.split(''))
}
}
}
// print the subsets out
for (s in subsets) {
$('body').append(subsets[s].join(', ') + '<br>')
}
Alternative, possibly nicer solution would be to use dynamic programming. Start with 3 and either remove last element or add next element. Check it out here: https://jsfiddle.net/p82fcs4m/
var set = [3, 3, 9, 9, 5].join('')
var subsets = []
take(set[0], set.substring(1))
function take(chosen, left) {
if(subsets.indexOf(chosen) != -1) {
return
}
subsets.push(chosen)
if (chosen.length > 1) {
take(chosen.substring(1), left)
}
if (left.length > 0) {
take(chosen.concat(left[0]), left.substring(1))
}
}
$('body').append(subsets.join('<br>'))
Try this:
function getSubArrays(arr) {
const subArrays = [];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i; j++) {
const subArray = arr.slice(i, j + i + 1);
subArrays.push(subArray);
}
}
}
Still O(n²) tho
I believe using Array.slice is the most clean way to do it, isn't it?
function getSubArrays(arr) {
const subArrays = [];
for (var i = 0; i < arr.length; i++) {
for (var j = i; j < arr.length; j++) {
subArrays.push(arr.slice(i, j + 1));
}
}
return subArrays;
}

Javascript: uniform length of subarrays [duplicate]

This question already has answers here:
Split array into chunks
(73 answers)
Closed 8 years ago.
I'm trying to split an array into chunks. The chunks should be as many as the function specifies. What I have already is
groupBySize = function(array, groupSize){
if(groupSize === 0){
return;
}
var groups = [];
var i,j,temparray;
for (i=0,j=array.length; i<j; i+=groupSize) {
temparray = array.slice(i,i+groupSize);
groups.push(temparray);
}
return groups;
};
groupByNumberOfGroups = function(array, NumberOfGroups){
var groupSize = Math.floor(array.length/NumberOfGroups);
var groups = this.groupBySize(array, groupSize);
// Let's make sure we get the right amount of groups
while(groups.length > NumberOfGroups){
console.log(groups.length + ">" + NumberOfGroups);
var last = groups[(groups.length-1)];
for(var j = 0; j< last.length; j++){
var temp = j;
while(groups[temp].length > groups[temp+1]){
temp++;
}
groups[j].push(last[j]);
}
groups.pop();
}
return groups;
};
This successfully splits the array up into the correct amount of chunks. I would like it to then make the length of each chunk as uniform as possible so if I were to split up an array like [1,2,3,4,5,6] into 4 chunks i would get [[1,2],[3,4],[5],[6]].
Any suggestions?
Another example of shortcomings: splitting up [1,2,3,4,5,6,7,8,9,10,11,12,13,14] into 8 chunks gives [[1,2,3,4,5,6,7],[8],[9],[10],[11],[12],[13],[14]]
Simple maths. If You have n items and want to split them into k chunks, every chunk will have n / k items. But what if n / k isn't an integer? Then some of the chunks will have n / k rounded down items and some will have n / k rounded down + 1 items. How many of them will have the + 1 items? n % k.
function distribute(a, k) {
var count = Math.floor(a.length / k);
var remain = a.length % k;
var result = [];
var index = 0;
for (var i = 0; i < k; i++) {
var number = count + (i < remain ? 1 : 0);
result.push(a.slice(index, index + number));
index += number;
}
return result;
}
distribute([1, 2, 3, 4, 5, 6, 7], 2);
--> [[1, 2, 3, 4], [5, 6, 7]]
Edit by Nordfjord: Shorter, but groups different values than the solution above:
groupByNumberOfGroups = function(array, numberOfGroups){
var groups = []
for(var i = 0; i < numberOfGroups; ++i) groups.push([]);
for(var i = 0; i < array.length; ++i) groups[i%numberOfGroups].push(array[i]);
return groups;
}
Try this,
var groupByNumberOfGroups = function( array, NumberOfGroups ){
var div = Math.floor( array.length / NumberOfGroups );
var mod = array.length % NumberOfGroups;
var result = [];
var lowerBound=0, upperBound=0;
for ( var k=0; k<NumberOfGroups; k++ ) {
lowerBound = ( upperBound === 0 ) ? ( ( k < mod ) ? k * ( div + 1 ) : k * ( div ) ) : upperBound
upperBound = ( k < mod ) ? ( lowerBound + div + 1 ) : ( lowerBound + div )
result[ k ] = array.slice( lowerBound, upperBound );
}
return result;
};
groupByNumberOfGroups([1,2,3,4,5,6], 4); // [[1, 2], [3, 4], [5], [6]]
groupByNumberOfGroups([1,2,3,4,5,6,7,8,9,10,11,12,13,14], 8); // [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13], [14]]
js fiddle : link

Categories