i was asked to define a function reduce, that has three parameters, an array, an unknown function, and a number, and reduces the array into a number
and this is was i was given before i was asked to define the function
reduce([1, 2, 3], function(total, number) {
return total + number;
}, 0); // should return 6
I am a bit clueless on what this is asking me to do to be completely honest
if i could at least get some guideline id be grateful
here is my attempt
var reduce = function(array, func, initial){
function func(){
}
for( var i = 0; i < array.length; i++){
func(initial, array[i]);
}
}
Try:
function reduce(list, f, acc) {
return list.length ?
reduce(list.slice(1), f, f(acc, list[0])) :
acc;
}
Simple.
You need to be sure to create a total variable which will be redefined after every function call. You were very close. Try this out:
var reduce = function(array, func, initial){
var total = initial,
arr_len = array.length;
for(var i = 0; i < arr_len; i++){
total = func(total, array[i]);
}
};
Related
Could someone please explain me what does this line of code actually means step by step.
arrRes.push(fn(arr[i]));
I understand the push part but I am struggling to grasp the code in the parenthesis.
The whole function looks like this :
function arrayCalc (arr, fn) {
arrRes = [];
for (let i = 0; i < arr.length; i++) {
arrRes.push(fn(arr[i])); // <--- this line here in the parenthesis
}
return arrRes;
};
Sorry if this is a dumb question but I've watched the tutorial video for five times and I just can't understand what that line exactly means.
Thanks!
there is some function fn passed as argument and array arr
arrRes.push(fn(arr[i])); - means:
take value from arr (index is i)
execute function fn with value as a parameter
whatever is result, push it to arrRes
example
function arrayCalc (arr, fn) {
arrRes = [];
for (let i = 0; i < arr.length; i++) {
arrRes.push(fn(arr[i]));
}
return arrRes;
};
const someArr = [1,2,3];
function someFunction(number) {
return number * 10;
}
function someOtherFunction(number) {
return `${number}_Z`;
}
console.log(arrayCalc(someArr, someFunction)) // [10, 20, 30]
console.log(arrayCalc(someArr, someOtherFunction)) // ['1_Z', '2_Z', '3_Z']
This is usually called a mapping: apply a function to each element of a collection... Thus if you have an array [1,2,3] and map it with a function that multiplies a number by 2, you will end with an array equals to [2,4,6].
To compute it, you need an array, arr and a function fn. Then for each element of arr in turn you apply fn to it and place the result at the end of the new collection. You can write it as:
arrRes = [];
for (let i = 0; i < arr.length; i++) {
var dummy = arr[i];
var mapped = fn(dummy);
arrRes.push(mapped);
}
I'd like to know how to make the second script return same value as the first one (by modifying MyObject), so I don't have to extend native objects.
Basically, I want to be able to call the function as parameter.functionName() instead of functionName(parameter).
Object.prototype.arraySum = function()
{
var sum = 0;
for(var i = 0; i < this.length; i++)
{
sum += this[i];
}
return sum;
}
console.log([1,2,3,4].arraySum()); /* return: 10 */
function MyObject()
{}
MyObject.prototype.arraySum = function()
{
var sum = 0;
for(var i = 0; i < this.length; i++)
{
sum += this[i];
}
return sum;
}
console.log([1,2,3,4].arraySum()); /* return: [1,2,3,4].arraySum is not a function */
I've looked through many questions here, but I haven't found the answer.
The array literal constructs an Array instance, there's no way how you could affect that. So to make this work with MyObject, you will need to change the code that invokes it.
A simple solution would a wrapper:
function MyObject(arr) {
this.array = arr;
}
MyObject.prototype.sum = function() {
var sum = 0;
for(var i = 0; i < this.array.length; i++) {
sum += this.array[i];
}
return sum;
};
console.log(new MyObject([1,2,3,4]).sum());
There are many other conveivable approaches, but none can change the fact that [1,2,3,4].arraySum() is not going to work.
console.log([1,2,3,4].arraySum())
[1,2,3,4] is an array and thus inherits from Array.prototype, not from MyObject. So if you really want to have parameter.functionName(), then you have to add arraySum function to Array.prototype.
But extending native prototypes is not a very good practice.
So you can write your own Array class:
function MyArray() {}
MyArray.prototype = new Array(); // all Array method will be available
MyArray.prototype.sum = function() {
console.log("My sum function")
}
var arr = new MyArray(); // it will produce an array-like object
arr.push(1,2,3);
arr.sum() // will log "My sum function"
https://jsfiddle.net/nuwanniroshana/2qoko562/
Array.prototype.sum = function() {
var sum = 0;
this.forEach(function(value) {
sum += value;
});
return sum;
};
var numbers = [1, 2, 3, 4, 5, 6, 7, 8];
var sum = numbers.sum();
console.log(sum);
var floats = [1.3, 85.2, 9.33, 1.24, 24.5, 6];
sum = floats.sum();
console.log(sum);
I create this function in order to have a random number for my first dice game.
function rollDice() {
return Math.floor(Math.random()*6 + 1);
}
Now I want create a new function dices() with a for loop in order to use how much dices the user need.
Usually I used length in a loop as this example:
for (var i=1; i < dices.length; i++) {
// do something
}
How you got any suggestions on how to fix this?
Thank you!
I don't know if it's really what you're looking for, but you can simply create a function and replace dice.length by the number of time you want to roll, see this example:
function rollManyDice(number) {
var diceNumber = 0;
for (var i = 0; i < number; i++) {
diceNumber += rollDice();
}
return diceNumber;
}
Something like this function if I understand your question? It returns an array with the results from the number of dices thrown.
function throwDice(num) {
var arr = [];
for (var i = 0, l = num; i < l ; i++) {
arr.push(rolldice());
}
return arr;
}
throwDice(3); // e.g. [3, 5, 1]
function rollDice(sides, amount){
var results = [];
for (var i=0; i < amount; i++){
results.push( Math.floor(Math.random()*sides + 1) );
}
return results;
}
should return a array of how ever amount of dice with the specified number of sides.
Can someone debug this code? I cannot for the life of me find the (run-time) error:
function generate_fibonacci(n1, n2, max, out){
var n = n1+n2;
if(n<max){
out.push(n);
generate_fibonacci(n2, n, max, out);
}
}
function generate_fibonacci_sequence(max){
var out = [1];
generate_fibonacci(0, 1, max, out);
return out;
}
function remove_odd_numbers(arr){
for (var i = 0; i < arr.length; i++) {
if(!(arr[i]%2==0)){
arr.splice(i, 1);
}
}
return arr;
}
function sum(array){
var total = 0;
for (var i = 0; i < array.length; i++) {
total+=array[i];
}
return total;
}
var fib_sq = generate_fibonacci_sequence(4000000);
console.log("Before: " + fib_sq);
remove_odd_numbers(fib_sq);
console.log("After: " + fib_sq);
console.log("WTH?: " + remove_odd_numbers([1,2,3,4,5,6,7,8,9]));
Output:
Before: 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578
After: 1,2,5,8,21,34,89,144,377,610,1597,2584,6765,10946,28657,46368,121393,196418,514229,832040,2178309,3524578
WTH?: 2,4,6,8
[Finished in 0.3s]
I'm going crazy or something. For some reason, all odd numbers are not being removed. But as you can see at the end, it works perfectly. I have no idea what is going on.
The problem in the original code is that when you remove the first 1 at index 0, the array gets shifted; now arr[i] is contains the second 1; but you just step over it.
You need to use while instead of if here, or copy to a separate list. This is an example for splicing:
function remove_odd_numbers1(arr){
for (var i = 0; i < arr.length; i++) {
// here
while (arr[i] % 2) {
arr.splice(i, 1);
}
}
return arr;
}
But it will be slow though. Better to create a new array:
function remove_odd_numbers2(arr){
var rv = [];
for (var i = 0; i < arr.length; i++) {
if (! (arr[i] % 2)) {
rv.push(arr[i]);
}
}
return rv;
}
Generally the best algorithm however is to use the same array, if the original is not needed, so that no extra memory is required (though on javascript this is of a bit dubious value):
function remove_odd_numbers3(arr){
var out = 0;
for (var i = 0; i < arr.length; i++) {
if (! (arr[i] % 2)) {
arr[out++] = arr[i];
}
}
arr.length = out;
return arr;
}
Notice however that unlike the splice algorithm, this runs in O(n) time.
Also, the Array.prototype.filter() is not bad, being a builtin. It also creates a new array and thus is comparable to the 2.
I'm not sure about this, however I doubt using splice is efficient compared to creating a new array.
function remove_odd_numbers(arr) {
var notOdd = [],
i = 0,
len = arr.length,
num;
for (; i < len; i++) {
!((num = arr[i]) % 2) && notOdd.push(num);
}
return notOdd;
}
EDIT: You should probably use the native filter function, as suggested by #Jack. I leave this answer as a reference.
Here is a really simple, fast way to do it. Using your data, it only took 48ms to complete. Hope this helps..
function noOdds(values){
return values.filter(function (num) {
return num % 2 === 0;
});
}
Because splice() modifies the array, your index will be off in the next iteration; you need to either decrease the loop variable, use a while loop like Antti proposed or iterate backwards like Crazy Train mentioned.
That said, the use of splice() is awkward to work with because it modifies the array in-place. This functionality can be easily accomplished using a filter function as well:
function remove_odd_numbers(arr)
{
return arr.filter(function(value) {
return value % 2 == 0;
});
}
This creates and returns a new array with only the even values.
Given the recency of this function, check the compatibility section how to handle browsers IE < 9. Many popular libraries, such as jQuery, underscore, etc. take care of this for you.
Update
Instead of filtering the array afterwards, it would be more memory efficient to only add the even values as you perform the recursion:
function generate_fibonacci(previous, current, max, callback)
{
var next = previous + current;
if (next < max) {
callback(next);
generate_fibonacci(current, next, max, callback);
}
}
function generate_fibonacci_sequence(max, callback)
{
callback(1);
callback(1);
generate_fibonacci(1, 1, max, callback);
}
var out = [];
generate_fibonacci_sequence(4000000, function(value) {
if (value % 2 == 0) {
out.push(value);
}
});
Instead of passing the out array, I'm passing a function to be called whenever a new sequence value is generated; the filtering is done inside that callback.
ES6 version from "Tabetha Moe" answer
function noOdds(arr) {
return arr.filter(value => value % 2 === 0);
}
function ArrayAdditionI(arr) {
var numbers = arr();
var arraySum = "";
for (var i = 0; i < numbers.length; i++) {
arraySum = arraySum + arr[i];
};
if (numbers.max() <= arraySum) {
arr = true
}
else if (numbers.max() > arraySum) {
arr = false;
}
return arr;
}
I need to find the numbers stored in an array called arr and check if they add up to or total the greatest number or whether they do not. If so, return true. If not, return false.
I am not sure I am calling the array correctly in the beginning.
Thanks
I actually wrote a library I use just for functions like this.
http://code.google.com/p/pseudosavant/downloads/detail?name=psMathStats.min.js
You would just do this:
var arr = [1,2,3,4,5,300];
if (arr.max() > arr.sum()){
// Max is greater than sum...
}
One warning though. This library prototypes the Array object which could mess up other scripting that uses for (var i in arr) on an Array, which you shouldn't ever do. I am actually almost done with v2 of the library with a number of new functions and it no longer prototypes the Array object.
You can just grab the .max() and .sum() methods from the code, and use them without the prototyping if you want though.
maxArray = function (arr) {
return Math.max.apply(Math, arr);
}
sumArray = function (arr) {
for (var i = 0, length = arr.length, sum = 0; i < length; sum += arr[i++]);
return sum;
}
You mean something like this?
function ArrayAdditionI(arr) {
for (var i = 0, sum=0; i < arr.length; i++) {
sum += arr[i];
}
return Math.max.apply( Math, arr ) <= sum;
}
function ArrayAdditionI(input) {
var arraySum, max;
arraySum = max = input[0];
for (var i = 1; i < input.length; i++) {
arraySum += input[i];
if(input[i] > max){
max = input[i];
}
};
return arraySum >= max;
}
If the numbers are positive, the answer is guaranteed - the sum is always greater than or equal to the max. If you need to calculate it, ddlshack's code looks good.
Looking at your code, there are a number of issues. First of all, arr() should error out. Arrays aren't functions, and trying to treat them as a function does nothing. Your array is already usable when it is passed in. Additionally, you want to initialize arraySum to 0, not "". The way you are doing it, the values in the array will be coerced into strings and concatenated together, which is not what you are looking for. Finally, arrays don't implement a max() method, but Math does, and functions/methods in javascript can be applied to an array in the manner shown by ddlshack and others.
There are some syntax errors: type missmatch, wrong assign and calls to method that doesn't exists. If I'm understanding what do you want to do, this is the correct code(if changing items order is not a problem):
function ArrayAdditionI(arr) {
var ret = false;
var arraySum = 0;
for (var i = 0; i < arr.length; i++) {
arraySum += arr[i];
}
if (arr.sort()[arr.length-1] <= arraySum) {
ret = true
}
return ret;
}