how to stop loop while using setTimeout function - javascript

const fruits = ['apple', 'mango', 'orange', 'date'];
let found = 0;
fruits.forEach((value, key) => {
if (found == 0) {
console.log("value", value)
setTimeout(() => {
if (value.length > 1) {
found = 1;
}
}, 200)
}
})
Stop loop when it get caught found=1 but after using setTimout it does not behave like this how to solve it

Does this what you want:
const fruits = ['apple', 'mango', 'orange', 'date'];
let found = 0;
for (var i = 0 ; i < fruits.length ; i++ ) {
const value = fruits[i];
if (value.length > 1) {
found = 1;
console.log("Founded", value)
break;
} else {
console.log("Value", value)
}
}
console.log("Found: ",found)

Related

Why in this example using callback function in forEach method gives wrong output?

I am trying to use callback function with forEach method to print in the console the result of 3 prompts but instead I have 5 outputs.
const personalMovieDB = {
genres: [],
writeYourGenres: function () {
for (let i = 1; i <= 3; i++) {
let favoriteGenre = [];
while (favoriteGenre == null || favoriteGenre == "") {
favoriteGenre = prompt(`Your favorite movie genre under number ${i}`);
this.genres[i - 1] = favoriteGenre;
}
this.genres.forEach((item, i) => {
console.log(`Favorite genre ${i+1} - ${item}`);
});
}
}
}
Just remove printing functionality from a loop
const personalMovieDB = {
genres: [],
writeYourGenres: function() {
for (let i = 1; i <= 3; i++) {
let favoriteGenre = [];
while (favoriteGenre == null || favoriteGenre == "") {
favoriteGenre = prompt(`Your favorite movie genre under number ${i}`);
this.genres[i - 1] = favoriteGenre;
}
}
this.genres.forEach((item, i) => {
console.log(`Favorite genre ${i+1} - ${item}`);
});
}
}
personalMovieDB.writeYourGenres()

rewrite an array of letters to numbers using dictionary

examples:
"heLLo" => 0.1.2.2.3
"javAscript" => 0.1.2.1.3.4.5.6.7.8
"hippopotomonstrosesQuippedaliophobia" => 0.1.2.2.3.2.3.4.3.5.3.6.7.4.8.3.7.9.7.10.11.1.2.2.9.12.13.14.1.3.2.0.3.15.1.13
my non-working code:
function wordPattern(word) {
var res = []
var dic = []
var count = 0
var pipa = word.toLowerCase().split("")
for (i=0;i<pipa.length;i++) {
if (!dic.includes(pipa[i])) {
dic.push({key: count, value: pipa[i]});
count ++
}
for (j=0;j<pipa.length;j++) {
res.push(dic.key[pipa[i]])
}
return res.join(".");
}
Thanks in advance
To associate characters to numbers, don't use an array, use an object:
function wordPattern(word) {
const numbersByChar = {};
let i = 0;
return [...word]
.map(char => numbersByChar[char] ?? (numbersByChar[char] = i++))
.join('.');
}
console.log(wordPattern('hello'));
console.log(wordPattern('hippopotomonstrosesquippedaliophobia'));
Or without the concise syntax that you might find more readable
function wordPattern(word) {
const numbersByChar = {};
let i = 0;
return Array.from(word)
.map((char) => {
if (numbersByChar[char] === undefined) {
numbersByChar[char] = i;
i++;
}
return numbersByChar[char];
})
.join('.');
}
console.log(wordPattern('hello'));
console.log(wordPattern('hippopotomonstrosesquippedaliophobia'));
hint 1 is that you can get a letter like: word[index]
so change your code to this:
function wordPattern(word) {
var res = []
var dic = []
var count = 0
for (i=0;i<word.length;i++) {
let dicItem = dic.find(x=>x.value==word[i]);
if(!dicItem) {
dic.push({key: count, value: word[i]});
res.push(count);
count ++;
}
else res.push(dicItem.key);
}
return res.join(".");
}

Change specific value in array and array is empty

I create new array and add to her specific values. I add in first index and first index has value, but if I add in second or more index, last indexes are empty and I don't know why. Here my code.
const inputs = [...document.querySelectorAll('.input')];
let timeout = null;
inputs.forEach((input, index) => {
input.addEventListener('keyup', () => {
clearTimeout(timeout);
let inputValue = Number(input.value);
timeout = setTimeout(() => {
if (index !== 1) {
let arr = [];
if (index === 0) {
arr[0] = inputValue;
} else if (index === 2) {
arr[1] = inputValue;
} else if (index === 3) {
arr[2] = inputValue;
} else if (index === 4) {
arr[3] = inputValue;
}
console.log(arr);
}
}, 1000);
});
});
Use of the "push" array function. Example:
const inputs = [...document.querySelectorAll('.input')];
let timeout = null;
let arr = [];
inputs.forEach((input, index) => {
input.addEventListener('keyup', () => {
clearTimeout(timeout);
let inputValue = Number(input.value);
timeout = setTimeout(() => {
arr.push(inputValue);
console.log(arr);
}, 1000);
});
});

Convert JS Array to a nested Object

What is the best way to convert:
['[Title A]','child A','child B', '[Title B]', 'child C', 'child D']
to:
{
0: {
'title': 'Title A',
'children': ['child A', 'child B']
}
1: {
'title': 'Title B',
'children': ['Child C', 'Child D']
}
}
I have this so far which checks on the presence of brackets [] and I tried to add this to an object with a dynamic index which increments during a for loop every time a title with brackets is found:
let index = 0;
let listObject = {};
for (const listItem of listItems) {
const titleValue = listItem.match(/\[(.*?)\]/);
if (titleValue) {
++index;
listObject[index].title = titleValue[1];
} else {
listObject[index].children = [listItem];
}
}
console.log(listObject);
For the sake of simplicity let's first make an array of objects:
const res = arr.reduce((acc, cur) => {
const titleValue = cur.match(/\[(.*?)\]/)
titleValue ?
acc.push({
title: cur,
children: []
}) :
acc[acc.length - 1].children.push(cur)
return acc
}, [])
Now you can use the spread operator to have the nested object:
{...res}
const array = ['[Title A]','child A','child B', '[Title B]', 'child C', 'child D'];
let objToPush = {};
let objToSend = {};
array.map((d) => {
if (/^\[[^\]]+\]$/.test(d)) {
if (Object.keys(objToPush).length > 0) {
objToSend[Object.keys(objToSend).length] = { ...objToPush };
objToPush = {};
}
objToPush.title = d.substring(1, d.length - 1);
} else {
objToPush.children = objToPush.children ? [...objToPush.children, d] : [d]
}
});
objToSend[Object.keys(objToSend).length] = { ...objToPush };
console.log('objToPush', objToSend);
it worked for me (JSFiddle https://jsfiddle.net/wepbzdfL/48/)
Just updated yours so the logic is sound. Can see what you tried.
Read up on creating new objects and arrays in JS, and when you can add to them.
let listItems = ['[Title A]', 'child A', 'child B', '[Title B]', 'child C', 'child D'];
let index = 0;
var listObject = {};
for (const listItem of listItems) {
const isTitle = listItem[0] == "[" && listItem[listItem.length - 1] == "]"
if (isTitle) {
++index;
listObject[index] = {
title: listItem.substring(1, listItem.length -1),
children: [] //Create Array
}; //Create Object
} else {
listObject[index].children.push(listItem); //Add to children array
}
}
console.log(listObject);
To add on why I used an index lookup, instead of regex,
Run this:
var testArray = [];
var arrayCount = 20000000;
var regexMatch = /\[(.*?)\]/;
for (var i = 0; i < arrayCount; i++) {
testArray.push("[" + makeid(Math.round(Math.random() * 10)) + "]")
}
console.log(testArray.length);
var start = new Date();
console.log(start.toString());
for (var i = 0; i < arrayCount; i++) {
var testItem = testArray[i];
if (testItem.match(regexMatch)) {
} else {
}
}
console.log("regex took " + (new Date().getTime() - start.getTime()) / 1000 + " seconds");
start = new Date();
for (var i = 0; i < arrayCount; i++) {
var testItem = testArray[i];
if (testItem[0] === "[" && testItem[testItem.length - 1] === "]") {
} else {
}
}
console.log("index lookup took " + (new Date().getTime() - start.getTime()) / 1000 + " seconds");
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
I don't know if it's the "best" way, but this is my solution:
const array = [
"[Title A]",
"child A",
"child B",
"[Title B]",
"child C",
"child D"
];
let index = -1;
const res = array.reduce((acc, curr) => {
if (/^\[[^\]]+\]$/.test(curr)) {
acc = {
...acc,
[++index]: { title: curr.substring(1, curr.length - 1), children: [] }
};
} else {
acc[index].children = [...acc[index].children, curr];
}
return acc;
}, {});
console.log(res);

javascript remove item from array, if an item already existing in array

following adds items to array:
var arrayOptions = [];
function AddToFilterOptionList(mode) {
arrayOptions.push(mode);
}
remove item from array:
function RemoveFromFilterOptionList(mode) {
var index = arrayOptions.indexOf(mode);
if (index !== -1) {
arrayOptions.splice(index, 1);
}}
for example if i call
AddToFilterOptionList('APPLE') - APPLE should be added to array.
If i again call
AddToFilterOptionList('APPLE+FRUIT') - it should remove the the item 'APPLE' from array arrayOptions and should add APPLE+FRUIT
Any time only one word that starts with APPLE can be in array.
How to find the word like 'APPLE' in javascript.
I tried with Match() which returns the matching word. IndexOf() returns 1 only if whole word is match but not start of word.
Cycle through the Array and then use the startsWith method.
void AddToFilterOptionList(String mode) {
for (i=0; i<arrayOptions.length; i++) {
if (mode.startsWith(arrayOptions[i] == 1)) {
array[i] = mode;
return; // found, so return
}
}
arrayOptions.push(mode); // should only get here if string did not exist.
}
You need to split by + characted and then loop over produced array to add/remove all items:
var arrayOptions = [];
function AddToFilterOptionList(mode) {
mode.split(/\+/g).forEach(function(el) {
var index = arrayOptions.indexOf(el);
if (index !== -1) {
arrayOptions.splice(index, 1);
}
else {
arrayOptions.push(el);
}
});
}
function RemoveFromFilterOptionList(mode) {
var index = arrayOptions.indexOf(mode);
if (index !== -1) {
arrayOptions.splice(index, 1);
}
}
AddToFilterOptionList('APPLE');
document.write('<p>' + arrayOptions); // expect: APPLE
AddToFilterOptionList('APPLE+FRUIT');
document.write('<p>' + arrayOptions); // expect: FRUIT
AddToFilterOptionList('APPLE+FRUIT+CARROT');
document.write('<p>' + arrayOptions); // expect: APPLE,CARROT
This will work assuming the 'this+that' pattern is consistent, and that we only care about the starting item.
http://jsbin.com/gefasuqinu/1/edit?js,console
var arr = [];
function remove(item) {
var f = item.split('+')[0];
for (var i = 0, e = arr.length; i < e; i++) {
if (arr[i].split('+')[0] === f) {
arr.splice(i, 1);
break;
}
}
}
function add(item) {
remove(item);
arr.push(item);
}
UPDATE:
function add (array, fruits) {
var firstFruit = fruits.split('+')[0]
var secondFruit = fruits.split('+')[1]
var found = false
var output = []
output = array.map(function (item) {
if (item.indexOf(firstFruit) > -1) {
found = true
return fruits
}
else return item
})
if (! found) {
array.push(fruits)
}
return output
}
var fruits = []
add(fruits, 'APPLE')
fruits = add(fruits, 'APPLE+GRAPE')
console.log(fruits[0]) // 'APPLE+GRAPE'
fruits = add(fruits, 'APPLE')
console.log(fruits[0]) // 'APPLE'
Try this, the code is not optimised though :P
<html>
<head>
<script src = "jquery-1.10.2.min.js"></script>
<script type = "text/javascript">
var itemList = [];
function addItem()
{
var item = $('#item').val();
if(item != '' || item != 'undefined')
{
if(itemList.length == 0)
itemList.push(item);
else
{
for(i=0;i<itemList.length;i++)
{
var splittedInputItems = [];
splittedInputItems = item.split("+");
var splittedListItems = [];
splittedListItems = itemList[i].split("+");
if(splittedListItems[0] == splittedInputItems[0])
{
itemList.splice(i,1);
itemList.push(item);
return;
}
}
itemList.push(item);
}
}
}
</script>
</head>
<body>
<input id="item" type = "text"/>
<input type = "button" value="Add" onclick="addItem()">
</body>
</html>
let items = [1, 2, 3, 2, 4, 5, 2, 7];
let item = 2;
for (let i = 0; i < items.length; i++) {
if (items[i] === item) {
items.splice(i, 1);
i = i - 1;
}
}
If you want to remove the element '2' from items array, it is a way.

Categories