How to stop pushing values in a loop? - javascript

I am running the following:
function wikiText() {
console.log(JSON.stringify(JSON.parse(JSON.stringify(spacetime)), null, 4));
var url="https://en.wikipedia.org/w/api.php?action=parse&disablelimitreport=true&format=json&prop=text|langlinks&noimages=true&mobileformat=true&page="+ curTitle + "&callback=?";
$.getJSON(url,function(data){
$.each(data, function(i, item) {
spacetime[0].Title.push(curTitle);
for(var i = 0; i < dateText.length; i++) {
d += dateText[i] + ' ';
}
var words = d.split(" ");
var array = words;
var newArray = array.filter(function(v){return v!==''});
for (const word of newArray) {
if (months.has(word)) {
spacetime[0].Time.months.push(word);
} else if (+word < 32) {
spacetime[0].Time.days.push(+word);
} else if (+word < 2200) {
spacetime[0].Time.years.push(+word);
} else if (/\w+/.test(word)) {
spacetime[0].Time.suffixes.push(word);
}
}
let pattern = new RegExp('^\/wiki\/');
doSelect("Location").siblings('td').find('a').each(function(index, el) {
result = $(this).attr('href').replace(pattern, '');
countryPage();
});
};
});
});
}
And that in reality is a function which is called by another function function newQuery() {.. wikiText();
That first bit of code then runs another function function countryPage() { but this one isn't pushing spacetime[0].Time...
However I get duplicated values like:
"days": [
27,
28,
27,
28,
19,
22,
27,
28,
19,
22,
27,
28,
19,
22,
I don't understand why it is duplicating the values as if it was saving them and re-pushing them each time the function is called.
I do have a jsFiddle just be patient for a bit as it is doing a lot of parsings.(see console.log).
I need:
"days": [
27,
28,
19,
22,

Related

How do I iterate though an array and do actions based on conditions?

My goal is the following:
Create a loop that compares the array of numbers provided, for the number 28.
Log over, if it is greater than 28, and under if it is less than 28.
Don't log anything if it is equal to 28.
Expected output:
2 is under
40 is over
31 is over
This is my code currently; I feel like I am so close, but I'm not sure.
var rando_array = [2, 40, 31, 29, 9, 12, 41, 90];
rando_array.sort();
for (var i = 0; i < var rando_array.length; i++) {
var Its;
if (i > 28) {
Its = "over";
} else if (i < 28) {
Its = "under";
}
console.log(rando_array[i] + "Its");
};
Since you wanted to loop though the array, this solution uses a for-loop.
The same result could be achieved using forEach , maps etc...
let rando_array = [2, 40, 31, 29, 9, 12, 41, 90];
for (var i = 0; i < rando_array.length; i++) {
if (rando_array[i] > 28) {
console.log(rando_array[i] + " is over")
} else if (rando_array[i] === 28) {
// Do nothing
/* Uncomment to log eqaul
console.log(rando_array[i] + " is equal")
*/
} else {
console.log(rando_array[i] + " is under")
}
};
let arr = [2, 40, 31, 29, 9, 12, 41, 90]
const max_value = 28
arr.filter(item => item > max_value).forEach(number => {
// console logs if num is greater than 28
console.log(number)
})

Add the elements of two dimensional array that have first element same [duplicate]

This question already has answers here:
A better way to group a multidimensional array
(1 answer)
Summing a 2D array by "group"
(2 answers)
Group and average array values based on index
(4 answers)
JavaScript sum multidimensional array element values
(6 answers)
Iterate over multi-dimensional array and return aggregated sum based on first index
(3 answers)
Closed 1 year ago.
I have following two dimensional array.
const arr = [
[56783, 43, 54, 64, 64],
[65424, 67, 56, 64, 22],
[56783, 45, 66, 23, 65]
];
I wanna add the values of internal array with the values of another internal array if both have first element same.
For above example arr[0][0] and arr[2][0] have the first element same, so the result should be like arr[56783, 88, 120, 87, 129]. Don't add the first element of internal array, for this example the first element is 56783. Thank you in advance.
You can try with
let arr = [
[56783, 43, 54, 64, 64],
[65424, 67, 56, 64, 22],
[56783, 45, 66, 23, 65]
];
for(let element in arr) {
let firstElement = arr[element];
for(let innerArrays in arr) {
if(arr[innerArrays][0] === firstElement[0] && element !== innerArrays){
for(let i = 1; i < firstElement.length; i++) {
firstElement[i] = firstElement[i]+arr[innerArrays][i]
}
//You can do this if you want to delete the element that is added to first
arr.splice(innerArrays, 1);
}
}
}
console.log(arr);
const arr = [
[56783, 43, 54, 64, 64],
[65424, 67, 56, 64, 22],
[56783, 45, 66, 23, 65]
];
function solve(arr) {
var m = {};
arr.forEach((ls) => {
var firstElement = ls[0];
if (!m[firstElement]) {
m[firstElement] = [];
}
m[firstElement] = mergeLists(ls, m[firstElement]);
});
var finalLs = [];
Object.keys(m).forEach((key) => {
finalLs.push(m[key])
});
return finalLs;
}
function mergeLists(a, b) {
if (a.length == 0)
return b;
if (b.length == 0)
return a;
var finalList = [a[0]];
for (var i = 1; i < a.length; i++) {
finalList.push(a[i] + b[i]);
}
return finalList;
}
console.log(solve(arr));
Solution:
const arrays = [
[56783, 43, 54, 64, 64],
[65424, 67, 56, 64, 22],
[56783, 45, 66, 23, 65]
];
// TODO: check if anything is undefined (would have to be done nearly everywhere)
// but thats not what you asked for
let result = [];
let same = [];
for (i in arrays) {
array = arrays[i]
for (j in arrays) {
if (j != i) {
innerarray = arrays[j]
if (array[0] == innerarray[0]) {
same.push([i, j]);
}
}
}
}
// TODO: check for duplicates => [ [ '0', '2' ], [ '2', '0' ] ]
// inside of same
r = 0;
for (p in same) {
partners = same[p];
temparrays = [];
for (o in partners) {
temparrays.push(arrays[partners[o]]);
}
temparray = [];
for (i in temparrays) {
array = temparrays[i];
for (j in array) {
if (j != 0) {
if (temparray[j] == undefined) {
temparray[j] = array[j];
} else {
temparray[j] = temparray[j] + array[j];
}
} else {
temparray[j] = array[j];
}
}
}
result[r] = temparray;
r++;
}
console.log(result);
Notes:
It has a very bad naming of varaibles and you should add declaration of varaibles (ex.: const, let) everywhere.
It is also not optimised in any way, and i think more complicated than necessary, but it does what you want.
BTW: i just took your text and converted it to code, you already explained what needed to be done.
My TODO:'s are there to give you hints how to evolve the code (without any optimizations taken into consideration).

Adding the item numbers in an array and returning the total within a function

Can someone help me understand how to return the total of all the items in the array added together? Here is my code below:
var numbers = [7, 55, 99, 27, 3, 1];
function addThemUp(numeros) {
for (var i = 0; i < numeros.length; i++) {
return numeros[i];
}
}
addThemUp(numbers);
alert(addThemUp);
There are some mistakes in the code in the alert calling, here is the one to do it.
var numbers = [7, 55, 99, 27, 3, 1];
function addThemUp(numeros) {
var total = 0;
for (var i = 0; i < numeros.length; i++) {
total+=numeros[i];
}
return total;
}
var t = addThemUp(numbers);
alert(t);
Add(+) each value in a lopp to a variable and return the summed-variable
var numbers = [7, 55, 99, 27, 3, 1];
function addThemUp(numeros) {
var total = 0;
for (var i = 0; i < numeros.length; i++) {
total += numeros[i];
}
return total;
}
var op = addThemUp(numbers);
alert(op);
Using Array#reduce
var numbers = [7, 55, 99, 27, 3, 1];
function addThemUp(numeros) {
return numeros.reduce(function(a, b) {
return a + b;
});
}
var op = addThemUp(numbers);
alert(op);

Recreating a lookup table in Javascript

So I have a spreadsheet for retrieving membership rates, the columns are Age, Duration & Rate. You simply look down the age column to find the age of the customer, then when you find that age you keep heading down to match it to the correct Duration, then in the final column will be the rate. A (very) small version of that might look like this;
Age,Duration,Rate
18,10,1.33
18,11,1.5
18,12,1.8
19,10,1.4
19,11,1.65
19,12,1.88
20,10,1.48
20,11,1.73
20,12,1.98
So someone age 19, duration 11 has a rate of 1.65. Someone age 20 with a duration of 12 has a rate of 1.98 - easy!
My question is two parts, I want to convert this into a web page where someone enters the age and duration to retrieve the rate. I'm pretty sure my best option for this is a two dimensional array like so;
var array = [[18,10,1.33],[18,11,1.5],[18,12,1.8] .. and so on];
are there any better options for this?
The second question is how do I best iterate over a two dimensional array (if that ends up being the best solution)? As I touched upon before I would need to be able to have an iteration that returns the rate based on a two criteria search. I believe this would consist of a two part iteration but iteration is such a weak spot for me that trying to grasp where in the loops to put my iterations is just brain melting. I think it would look something like so;
for (var i = 0; i < array.length; i++){
for (var j = 0; j < array[i].length; j++){
//Do something... I think something like this
If array[][j] == ageImLookingFor && array[][j+1] == durationImLookingFor
then return array[][j+2] (which is the rate)
}
}
Any help, advice or ideas I would be super grateful
A better option than using an array is to use an object (or Map) with properties (keys) that correspond to valid combinations of age and duration, effectively indexing your data by that key:
var list = {
'18_10': { age: 18, duration: 10, rate: 1.33 }
'18_11': { age: 18, duration: 11, rate: 1.5 },
'18_12': { age: 18, duration: 11, rate: 1.8 },
// .. and so on
};
This way you do not have to iterate over an array (cf. your question #2), but given an age and a duration (let's say in variables that have those names), you can write this to get the matching item:
var item = list[age + '_' + duration];
Of course, you should check that age and duration are valid integer numbers and that the item could be undefined when the combination is not known.
Here is a simple snippet (without any checks) you could use to base your web form on. It builds the above mentioned object from an array having the data.
// Data in array -- will be keyed later
var arr = [
{ age: 18, duration: 10, rate: 1.33 },
{ age: 18, duration: 11, rate: 1.5 },
{ age: 18, duration: 12, rate: 1.8 },
{ age: 19, duration: 10, rate: 1.4 },
{ age: 19, duration: 11, rate: 1.65 },
{ age: 19, duration: 12, rate: 1.33 },
{ age: 20, duration: 10, rate: 1.48 },
{ age: 20, duration: 11, rate: 1.73 },
{ age: 20, duration: 12, rate: 1.98 },
];
// Build map, keyed by age/duration. It will look like:
// {
// '18_10': { age: 18, duration: 10, rate: 1.33 },
// '18_11': { age: 18, duration: 11, rate: 1.33 },
// ...etc
// }
mapByAgeDuration = {};
for (var i=0; i < arr.length; i++) {
mapByAgeDuration[arr[i].age + '_' + arr[i].duration] = arr[i];
}
// Fast retrieval function:
function getItemFor(age, duration) {
return mapByAgeDuration[age + '_' + duration];
}
// I/O
var button = document.getElementById('findRate');
var inputAge = document.getElementById('age');
var inputDuration = document.getElementById('duration');
var outputRate = document.getElementById('rate');
button.onclick = function() {
var age = inputAge.value;
var duration = inputDuration.value;
// Retrieve item for this age and duration
var item = getItemFor(age, duration);
// Output rate
outputRate.textContent = item !== undefined ? item.rate
: 'not a valid combination';
}
Age (18 - 20): <input id="age"><br>
Duration (10 - 12): <input id="duration"><br>
<button id="findRate">Find Rate</button><br>
Rate: <span id="rate"></span><br>
Q1: You can use a hash table for your lookup.
var data = [[18, 10, 1.33], [18, 11, 1.5], [18, 12, 1.8], [19, 10, 1.4], [19, 11, 1.65], [19, 12, 1.88], [20, 10, 1.48], [20, 11, 1.73], [20, 12, 1.98]],
object = {};
data.forEach(function (a) {
object[a[0]] = object[a[0]] || {};
object[a[0]][a[1]] = a[2];
});
// usage
document.write(object[19][11] + '<br>');
document.write(object[20][12] + '<br>');
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');
Q2: A proposal with Array#some()
If you have sorted data, you could insert a short circuit, if the values are greater then needed.
var data = [[18, 10, 1.33], [18, 11, 1.5], [18, 12, 1.8], [19, 10, 1.4], [19, 11, 1.65], [19, 12, 1.88], [20, 10, 1.48], [20, 11, 1.73], [20, 12, 1.98]],
object = {};
function getValue(p1, p2) {
var result;
data.forEach(function (a) {
if (a[0] === p1 && a[1] === p2) {
result = a[2];
return true;
}
// short circuit for not found values
return a[0] > p1;
});
return result;
}
// usage
document.write(getValue(19, 11) + '<br>');
document.write(getValue(20, 12) + '<br>');
Another approach is to leverage on the array.filter function.
You have to reshape your data into an objects array:
var rates = [
{'age':'18','duration':'10','rate':'1.33'},
{'age':'18','duration':'11','rate':'1.5'},
{'age':'19','duration':'12','rate':'1.8'}
];
function filterRate(item){
if(item.age == this.age && item.duration == this.duration)
return item;
}
function getRateByAgeDuration(age, duration){
res = null;
try{
res = rates.filter(filterRate, {'age':age, 'duration':duration})[0].rate;
}
catch(ex){ console.log(ex);}
return res;
}
document.write(getRateByAgeDuration('18', '10'));
It depends. If you use hashes, you will have O(1) time on average, but O(n) on worst case.
If you prefer to optimize the worst case, you can use binary search to achieve O(lg n) both on average and worst cases.
function binarySearch(array, data, from=0, to=array.length) {
if(from >= to) return -1; // not found
var m = Math.floor((from+to)/2);
for(var i=0; i<data.length; ++i) {
if(data[i] < array[m][i]) return binarySearch(array, data, from, m);
if(data[i] > array[m][i]) return binarySearch(array, data, m+1, to);
}
return m;
}
var idx = binarySearch(array, [18,12]);
if(idx > -1) array[idx];

Iterating over Arrays in Javascript

I am a JavaScript newbie. I'm trying to practice some sample JavaScript problems. I'm a little stuck when it comes to this question about iterating over arrays. Can anyone point me in the right direction?
I am trying to take the values in oldArray, add 5 to each of them, and store in newArray.
var oldArray = [12, 45, 6, 23, 19, 20, 20, 15, 30, 42];
var newArray = [];
function plusFive(oldArray[i]) {
for (var i = 0; i < oldArray.length; i++) {
newArray.push(oldArray[i]) + 5) };
}
}
Bug in your code is an additional parenthesis and closing brace in push statement line, just remove them. Also there is no need to set function parameter here since both array are accessible inside the function, if you want to pass then you need to change it to function plusFive(oldArray), and call the function with array as parameter.
newArray.push(oldArray[i] + 5) ;
//-----------------------^----^-
Working snippet :
var newArray = [];
function plusFive(oldArray) {
for (var i = 0; i < oldArray.length; i++) {
newArray.push(oldArray[i] + 5)
};
}
plusFive([1,2,4,6,32,44]);
document.write(
'New array :' +
'<pre>' + JSON.stringify(newArray) + '</pre>'
);
Function without array as parameter
var oldArray = [12, 45, 6, 23, 19, 20, 20, 15, 30, 42];
var newArray = [];
function plusFive() {
for (var i = 0; i < oldArray.length; i++) {
newArray.push(oldArray[i] + 5)
};
}
plusFive();
document.write(
'Old array :' +
'<pre>' + JSON.stringify(oldArray) + '</pre>' +
'New array :' +
'<pre>' + JSON.stringify(newArray) + '</pre>'
);
But it's better to use map() for creating a modified array from an existing array
var oldArray = [12, 45, 6, 23, 19, 20, 20, 15, 30, 42];
var newArray = oldArray.map(function(v) {
return v + 5;
});
document.write(
'Old array :' +
'<pre>' + JSON.stringify(oldArray) + '</pre>' +
'New array :' +
'<pre>' + JSON.stringify(newArray) + '</pre>'
);
Your code is almost right, but you closed parenthesises incorrectly, and you need to name the function argument correctly. For function arguments, you're just giving labels. You can't name a variable something[a], and an argument cannot be named something[a].
Try:
var oldArray = [12, 45, 6, 23, 19, 20, 20, 15, 30, 42];
var newArray = [];
function plusFive(oldArray) {
for (var i = 0; i < oldArray.length; i++) {
newArray.push(oldArray[i] + 5)
}
}
plusFive();

Categories