How to concatenate operators in javascript? - javascript

I am writing next_previous() function for pagination purpose, I have for loop which is moving from 0 to the given length. I want to use the same loop for two cases from 0 to 10 and from 10 to 0.
for (var i = 0; i < 10; i++) {
}
for (var i = 10; i > 0; i--) {
}
to use both cases in one loop I am doing something like this but not working
var i = 0; a = '', b = '';
if(somevar === true){
i = 0 , a = '++', var b = '<';
}else{
i = 10 , a = '--', var b = '>';
}
for (i; i +b+ 0; i+a) {
}
now problem is javascript not allowing concatenation this way, how can I achieve this?
See screenshot

Try this approach which uses for the logic part ( increment and condition ) functions.
ES6
let i = 0;
let a;
let b;
let count = 0;
let somevar = true;
if(somevar) {
i = 0;
count = 10;
a = () => i++;
b = () => i < count;
} else {
i = 10;
count = 0;
a = () => i--;
b = () => i > count;
}
for (; b(); a()) {
console.log(i);
}
ES5
var i = 0;
var a;
var b;
var count = 0;
var somevar = true;
if(somevar) {
i = 0;
count = 10;
a = function() { i++; };
b = function() { return i < count; };
} else {
i = 10;
count = 0;
a = function() { i--; };
b = function() { return i > count; };
}
for (; b(); a()) {
console.log(i);
}

It seems like you are looking for an eval solution, but this really is not how one would approach this problem. Rather go for a functional design:
function forward(cb) {
for (var i = 0; i < 10; i++) cb(i);
}
function backward(cb) {
for (var i = 10; i > 0; i--) cb(i);
}
const loop = somevar ? forward : backward;
loop(i => {
…
});

This answer is a less-lazy version of #BiswajitPanday's answer. I would have edited his answer instead, but I realized that it's been a week since this question was posted, so an edit on his answer wouldn't be as fruitful since OP wouldn't be notified
Here is an eval solution:
function loopFoo(backwardsDirection, callback) {
if(backwardsDirection === true) {
var i = 10, b = '>', c = 0, a = '--';
} else {
var i = 0, b = '<', c = 10, a = '++';
}
for (i; eval("i" + b + c); eval("i" + a)) {
callback(i);
}
}
console.log("Forwards:");
loopFoo(false, console.log);
console.log("Backwards:");
loopFoo(true, console.log);
console.log("Forwards:");
loopFoo(false, console.log);
That function (eval) is generally frowned upon though, I would go with #Bergi's solution, if not that, #Suren's, and if not his either, my solution.

Just use eval(i+b+10) instead of i+b+10

Related

Array.push inside 2nd nested For Loop

Why Array.push doesnt work inside Nested For Loop? But it works if I replace 2nd for Loop with forEach
var longestCommonPrefix = function (strs) {
if (strs.length === 1) {
return strs.join('')
}
let reference = strs[0].split('');
let answer = [];
let final = [];
for (let i = 1; i < strs.length; i++) {
let check = strs[i].split('')
for (let x = 0; x < reference.length; x++) {
if (reference[x] === check[x]) {
answer.push(check[x]) //WHY THIS WONT WORK?
} else return
}
reference = answer
}
console.log(answer)
};
longestCommonPrefix(["flower", "flow", "flight"]);
return is used to exit the function, use break to only exit the loop
var longestCommonPrefix = function(strs) {
if (strs.length === 1) {
return strs.join('')
}
let reference = strs[0].split('');
let answer = [];
let final = [];
for (let i = 1; i < strs.length; i++) {
let check = strs[i].split('')
for(let x = 0 ; x<reference.length ; x++){
if(reference[x] === check[x]){
answer.push(check[x]) //WHY THIS WONT WORK?
}else break
}
reference = answer
}
console.log(answer)
};
longestCommonPrefix(["flower", "flow", "flight"])

how can I better run my code in javascript?

The exercise is as follows, given an array with multiple arrays inside, return the sum of the product subtraction with the LMC. I managed to create the code, but is passing 12000ms of response and wanted to optimize my code, I still have difficulty with it, can you help me? Follow the code below.
The expected result is 840.
let pairs = [[15,18], [4,5], [12,60]];
function sumDifferencesBetweenProductsAndLCMs (pairs)
{
let product = [];
let prodResult = 1;
let LMC = [];
let result = 0;
// take a product
for(let i = 0; i < pairs.length;i++)
{
for(let j = 0; j < pairs[i].length;j++)
{
prodResult *= pairs[i][j]
}
product.push(prodResult);
if(prodResult != 0)
{
prodResult = 1
}
}
// take a LMC
for(let i = 0; i < pairs.length;i++)
{
let m = pairs[i][0];
let n = pairs[i][1];
let a = pairs[i][0];
let b = pairs[i][1];
let mmc = 0;
let r = 0
do
{
r = m%n;
m=n;
n=r;
} while (r != 0);
mmc = (a * b)/m
LMC.push(mmc)
}
for(let i = 0; i < product.length; i++){
result += product[i]-LMC[i]
}
return result
}
console.log(sumDifferencesBetweenProductsAndLCMs(pairs));
You can do all calculation in single loop only which will reduce your run time complexity.
let pairs = [[15,18], [4,5], [12,60]];
function sumDifferencesBetweenProductsAndLCMs (pairs) {
let result = 0;
// take a product
for(let i = 0; i < pairs.length;i++) {
let prodResult = 1;
for(let j = 0; j < pairs[i].length;j++) {
prodResult *= pairs[i][j]
}
const lcmResult = lcm(pairs[i][0], pairs[i][1]);
result += prodResult - lcmResult;
}
return result
}
function lcm(a, b) {
return (a / gcd(a, b)) * b;
}
function gcd(a, b) {
if (a === 0) {
return b;
}
return gcd(b % a, a);
}
console.log(sumDifferencesBetweenProductsAndLCMs(pairs));
.as-console-wrapper {
top: 0;
}

Fixing Fibonacci sequence script (javascript)

I am trying to write a script that will create numbers in Fibonacci order, I don't understand why this is not working.
var output = [];
var n = output.length;
var nextNum = output[n-1] + output[n-2];
function fibo (numQuantity) {
for (var i=1; i<numQuantity ; i++)
{
if (n>1){
output.push(nextNum);
console.log(output);
}
else if (n<2)
{output.push(1);
console.log(output);}
}
}
In your original code your n never changes as you only assigned it on start.
var output = [];
function fibo (numQuantity) {
for (var i=1; i<numQuantity ; i++)
{
var n = output.length;
var nextNum = output[n-1] + output[n-2];
if (n>1){
output.push(nextNum);
console.log(output);
}
else if (n<2)
{
output.push(1);
console.log(output);
}
}
}
fibo(10)
In Javascript numbers are passed by value not reference so they are not the same object in memory. So when the array length changes your n value stays at 0 because they are not the same object.
function fibo(numQuantity) {
let output = [0, 1];
if(numQuantity < 2) {
return output.slice(0, numQuantity);
}
for(let i = 2; i < numQuantity ; i++) {
const n = output.length
output.push(output[n - 1] + output[n - 2])
}
return output;
}
console.log(fibo(1))
console.log(fibo(2))
console.log(fibo(3))
console.log(fibo(4))
Check this fiddle: https://jsfiddle.net/37a4burz/
You need to add n++ to end of your code and change end condition.
Here is full code:
var output = [];
var n = output.length;
var nextNum = output[n-1] + output[n-2];
function fibo (numQuantity) {
for (var i=1; i<= numQuantity ; i++)
{
if (n==0) {
output.push(0);
console.log(output);
}
else if (n==1) {
output.push(1);
console.log(output);
}
else if (n>1) {
output.push(output[n-1] + output[n-2]);
console.log(output);
}
n++;
}
}
fibo(7);

How to make for loop log line by line with 1sec delay in JS

My code will log all 10 lines in the order that I want (descending triangle), but I need it to delay 1 second before logging each successive line. I tried putting a setTimeout before the for loop, but that just caused a 1 second delay before printing all 10 lines concurrently.
function minusTen(num) {
var arr = '';
for (var i = num; i > 0; i--) {
arr += '*';
}
var newArr = arr.split('');
for (var j = num; j > 0; j--) {
newArr.pop();
console.log(newArr.join(' '));
}
}
minusTen(10);
I can use jQuery but I'd like to avoid having to implement Bootstrap if possible.
Thank you!
you can use setTimeout for it but then you will have to keep setTimeout inside the for loop. you can also use setInterval here and clear the interval if num becomes 0. something like this:
function minusTen(num) {
var arr = '';
for (var i = num; i > 0; i--) {
arr += '*';
}
var newArr = arr.split('');
var interval = setInterval(function(){
newArr.pop();
console.log(newArr.join(' '));
num--;
if(!num)
clearInterval(interval);
}, 1000)
}
minusTen(10);
You can use a function. Check the .length of newArr, if greater than 0, call function again
function minusTen(num) {
var arr = '';
for (var i = num; i > 0; i--) {
arr += '*';
}
var newArr = arr.split('');
function fn() {
if (newArr.length)
setTimeout(function() {
console.log(newArr.join(" "));
newArr.pop();
fn()
}, 1000)
else
console.log("done, newArr.length:", newArr.length);
}
fn()
}
minusTen(10);
function minusTen(num) {
var arr = '';
for (var i = num; i > 0; i--) {
arr += '*';
}
var newArr = arr.split('');
function printLine(counter){
var k = counter;
window.setTimeout(function(){
console.log(newArr.join(' '));
newArr.pop();
}, k*1000);
console.log(k);
}
for (var j = num; j > 0; j--) {
printLine(j);
}
}
minusTen(10);
It's straightforward with async/await. delay holds the execution of the code for a specified amount of time.
async function minusTen(num) {
var arr = '';
for (var i = num; i > 0; i--) {
arr += '*';
}
var newArr = arr.split('');
for (var j = num; j > 0; j--) {
newArr.pop();
await delay(1000)
console.log(newArr.join(' '));
}
}
function delay(time) {
return new Promise((resolve) => setTimeout(resolve, time))
}
minusTen(10);
You can use setTimeout with an offset. Just add whatever parameters you need to the log function.
function log(offSet) {
setTimeout(() => {
const str = new Array(offSet + 1).join('*');
console.log(str);
}, 1000 * offSet);
}
for(let i = 1; i < 11; i ++) {
log(i);
}
https://jsfiddle.net/ycreaL9w/
If you wanted to reduce your code footprint a little you could do something like this:
const printStars = (n) => {
// Make sure we don't try to print zero stars
if (n > 0) {
// Fill an array with n stars
const arr = Array(n).fill('*').join(' ');
console.log(arr);
// After a second, reduce n by 1 and call
// the function again
setTimeout(() => printStars(--n), 1000);
}
}
printStars(10);
DEMO
It's worth pointing out here, however, that IE/Opera don't support Array.fill.
If you need to support them use an for/loop like in your example. Here I've separated out that code into its own function.
const getStars = (n) => {
let arr = [];
for (let i = 0; i < n; i++) {
arr.push('*');
}
return arr.join(' ');
}
const printStars = (n) => {
if (n > 0) {
console.log(getStars(n));
setTimeout(() => printStars(--n), 1000);
}
}
DEMO 2

Random pick items of an array in javascript

I have the following code in my index.html page
<body>
<script type="text/javascript" src="words.js"></script>
<script>
var words = [];
window.onload = function () {
words = getwords();
};
</script>
</body>
And in word.js file
function getwords() {
var block = [];
var keyword = ['HELLO', 'CYCLE', 'APPLE', 'albatross', 'platform', 'OPERA', 'COURT', 'HOUSE', 'NEWEST', 'AEROPLANE', 'SCIENTIST', 'CORRIDOR', 'BUTTERFLY'.
'MUSICAL', ' AUSTRALIA', 'XYLOPHONE', 'TAPESTRY', 'DREAM', 'NEEDLE', 'GIRAFFE'
];
var index = [];
for (var p = 0; p < keyword.length; p++) {
index[p] = 0;
}
for (var i = 0; i < 8; i++) {
var x = Math.floor(Math.random() * (keyword.length - 1));
for (var j = 0; j <= i; j++) {
if ((words[j] !== keyword[x]) && (index[x] !== 1)) {
block[i] = keyword[x];
index[x] = 1;
}
}
}
return block;
}
I want my getwords function to return any 8 words from keyword array everytime it is called in the onload and it should get stored in words array and those words shouldnt be repaeted next time. However my code doesn't work. May I know my mistake? Please help!
I tried
function getwords(){
var block = [], index =[];
var rem = keyword.length -1;
for(var p=0 ;p <(rem+1) ;p++)
{
index[p]=0;
}
for(var i = 0; i < rem; ++i) keys.push(i);
for(var i=0; i<8 ;i++) {
var x = Math.floor(Math.random() * rem);
while(index[x]===1)
{
x = parseInt(Math.random() * rem);
}
block.push(keyword[x]);
index[x]=1;
}
return block;
}
Still gives some same words on second call.
A small mistake has cost you this problem ...
While storing the indexes in the index array you are using index[p] = 0;
But which should be
for(var p = 0; p < keyword.length; p++) {
index[p] = p;
}
here is the Working Example
I can give you a nicer approach. Tested to be OK, have a try.
var keyword=[
'HELLO', 'CYCLE', 'APPLE', 'albatross', 'platform',
'OPERA', 'COURT', 'HOUSE', 'NEWEST', 'AEROPLANE',
'SCIENTIST', 'CORRIDOR', 'BUTTERFLY', 'MUSICAL',
'AUSTRALIA', 'XYLOPHONE', 'TAPESTRY', 'DREAM',
'NEEDLE', 'GIRAFFE'];
var keys = [];
for(var i = 0; i < keyword.length; ++i) keys.push(i);
function getwords(count){
var block = [];
// first.
// pick and remove [count] times. Becareful when keys goes empty.
while(count > 0 && keys.length > 0) {
var x = parseInt(Math.random() * keys.length);
block.push(keyword[keys[x]]);
keys[x] = keys[keys.length-1];
keys.pop();
--count;
}
return block;
}
console.log(getwords(8));
console.log(getwords(8));
console.log(getwords(8));
What you mean by "doesn't work"? What shows the console?
'BUTTERFLY'.'MUSICAL'. There's a dot instead of a comma.
Hope it helps.

Categories