let arr = [2, 5, 7, 9, 12, 14, 20];
let arr2 = [10, 50, 70, 80, 90, 120, 150];
let arr3 = [];
for (i = 0; i < arr.length; i++) {
while (arr[i] < arr2[i]) {
arr[i] += arr[i];
}
arr3.push(arr[i]);
}
console.log(arr3);
I need to add the base values in the first array elements as long as the first array element is smaller than the second array elements. But i end up doubling the values. I simply need to increment the values in the first array by the base values.
For example: I want:
2 + 2 = 4
4 + 2 = 6
6 + 2 = 8
as long as its less than 10.
so the result array should be: [8, 45, 63, 72, 84, 112, 140]
How to make that happen. I know I am missing something very simple here.
Isn’t there a simple way to do this? If I can just keep adding the initial value to the value until the last possible value is reached. What would be the simplest logic for it?
Yes, my bad sorry. The result array should be the maximum value of each element less than the arr2 element. And the value should increment by itself. So if the value in arr is 10 and its corresponding arr2 value is 90, then the result value should be 80.
First of all, your values are doubling because you’re reassigning them. You probably wanted to do something like:
for (let i = 0; i < arr.length; i++) {
let counter = arr[i];
while (counter < arr2[i]) {
counter += arr[i];
}
arr3.push(counter);
}
Now, secondly, even if you would have done it, this wouldn’t work either because you will still do the last addition after comparing values. You might do a little trick:
for (let i = 0; i < arr.length; i++) {
let counter = arr[i];
while (counter < arr2[i]) {
counter += arr[i];
}
arr3.push(counter - arr[i]); //Here's the trick
}
or, something like this, which is slightly more readable:
for (let i = 0; i < arr.length; i++) {
let counter = arr[i];
while (counter + arr[i] < arr2[i]) {
counter += arr[i];
}
arr3.push(counter);
}
If you return to this problem later on you may be interested to know that an operation on two lists like this is known as a zip or zipWith in other languages
It’s a nifty generalisation, but it’s not important to know or anything, just thought you might find it interesting
You can imagine it as taking a pair of lists, creating a list of pairs, and then reducing over the list of pairs
Edit: changed map to reduce, though more precisely it’s a scan
@camperextraordinaire, first of all, this is @umairhp’s code. I just pointed out how to make his code work.
Secondly, it’s not the code that doesn’t account for rounding errors, it’s the way language works itself. It’s like saying that const add = (x, y) => x + y; is wrong, because add(.1, .2) doesn’t work
Now, if you want to discuss my code, discuss this ‘unreadable gibberish’:
const solveUmairhpProblem = (arr1, arr2) => arr1.map((n, i) => n >= arr2[i] ? n : arr2[i] % n ? arr2[i] - arr2[i] % n : arr2[i] - n);
arr2[i] - arr2[i] can be simplified to 0 - is this what you want?
A map is the wrong abstraction when considering multiple arrays
Using the index with a map is bad form and should probably not have been allowed in the standard
If you intended to find arr2[i] - arr1[i] consider that arr2[i] - arr1[i] doesn’t work for 10 and 0.3, and also consider the fact that you have n already and don’t need to index arr1…
I might have created some confusion given how many posts are here. I was replying to ‘doubling’ problem in the first post. And by saying ‘to make it work’ I clearly meant this “I simply need to increment the values in the first array by the base values.”
for (1) I misread the line as it was quite dense, my bad!
It’s not clear to me what (float) % (float) is meant to mean anyway, but JS is weird!
(2) and (3) are really down to the same thing, interpretation of what a map should be
In many languages, especially functional ones, (of which javascript is one in disguise!) a map refers to using a pure function that uses only the element of a list it’s currently operating on with no side effects
It makes reasoning about things that happen to large lists very easy, all you need to do is look at the function, think about what it does to a single (number/list/whatever) and you know what the final list looks like.
There’s also room with pure maps (of which JS can’t guarantee )for some really cool optimisations where the array can be operated on in parallel and things like that
reduce or fold as it’s known elsewhere is an incredible tool - I won’t spoil how but it’s more general than the rest of these, and the rest of these can be implemented with it (and it’s still pure)
forEach is the abstraction that’s like map that’s associated with impure side effects such as mutation
The following should be in JS and aren’t:
zip is the abstraction that takes two lists and combines them to a list of pairs which can later be merged together
zipWith is the abstraction that takes two lists, examines the elements of each list together and calls a function of two variables on their elements
Note that zipWith is like a map over two arrays at once with a function of two variables
It’s a conceptual difference that comes from functional programming
A pure function doesn’t depend on the environment or state, and returns the same thing each time
The function
const f = function(x) {
return arr2[x];
}
depends on the values of arr2 at the given time its called and doesn’t return the same value each time it’s called
The common use of map as an abstraction is to use map(f) where f is some pure function, operating over a collection
I’m not very good at explaining things which is probably why I’m not a teacher - I don’t think I can do a very good job of explaining why this is a good idea or why having both map and forEach and why they ought to be treated differently is important
If my next reply is slow I’ve fallen asleep, it’s 2:30am and I’ve polished off a bottle of wine