understanding the return keyword - javascript

I have this:
validateForm = () => {
for (let i = 0; i < formInputs.length; i++) {
const inputName = formInputs[i];
if (!this.state.form[inputName].length) {
return false;
}
}
}
which im refactoring in to this:
validateForm2 = () => {
Object.keys(this.state.form).map(input => {
if(!this.state.form[input].length) {
return false
}
return true;
})
}
the first one works, when i fill in my form and the function returns true, if one is empty it returns false.
however i cant seem to quite understand the return keyword to get the same result.
Object.keys says it returns an array but even if I say return Object.keys... or else {return true} I don't seem to get the same result. what am I misunderstanding about return?

You could use Array#every, which uses the return value for a short circuit and for returning the check of all truthy items.
validateForm2 = () =>
Object.keys(this.state.form).every(input => this.state.form[input].length);
Array#map utilizes the return value as new item for each item of the array for a new array, which is dicarded in the given example.

In the first example you have only one (arrow) function which returns either false or undefined.
In the second example you have outer (arrow) function that never returns anything - undefined to the calling code, and the second function that you pass as a parameter to Array.map method. return statements inside the parameter function are not returning anything from the outer function.
validateForm2 = () => {
var emptyItems = Object.keys(this.state.form).filter(input => {
return !this.state.form[input].length;
});
return emptyItems.length == 0;
}

You could modify your function to do what you want it to do.
validateForm2 = () => {
return Object.keys(this.state.form).every(input => {
return this.state.form[input].length;
})
}
You are checking that every property has a length (true). If one of them doesn't, your function returns false.

I think you can avoid using .map in favor of .every() which iterates over every single element and checks whether it has a length greater than zero.
const validateForm = (form) => Object.values(form).every((field) => field.length);
let semiEmptyForm = {
firstField : "",
secondfield : "notEmpty"
};
let nonEmptyForm = {
firstField : "notEmpty",
secondfield : "notEmpty"
};
console.log(validateForm(semiEmptyForm))
console.log(validateForm(nonEmptyForm))

Related

filter and regex issue

I want to filter an array with a function.
if (this.pendingItems.customer?.emailAddresses) {
this.pendingItems.customer.emailAddresses.filter(email => {
isEmailValid(email);
});
}
the function isEmailValid()
export function isEmailValid(s: string): boolean {
const re =
/^[a-z0-9+-][a-z0-9_+-]*(\.[a-z0-9_+-]+)*#([a-z0-9-]+\.)+[a-z0-9-]{2,}$/i;
return re.test(s);
}
return the correct response (true or false) with the emails(test#email.com and test2email) I pass it, but the filter don't work.
You need to modify your expression slightly. The method you pass to the filter function should return true/false but it always returns void (which will be cast to false).
filter(email => isEmailValid(email))
or
filter(isEmailValid)
or
filter(email => { return isEmailValid(email) })
In case you missed it - you forgot to return the result of the isEmailValid ;)
So the solution was:
if (this.pendingItems.customer?.emailAddresses) {
this.pendingItems.customer.emailAddresses = this.pendingItems.customer.emailAddresses.filter(isEmailValid);
}
I forgot to reassign the variable ;p

How to use recursion in JavaScript for try do function?

I want to make this code prettier with recursion.
findModel = function(oldModel, ...modelStyles) {
let model = oldModel.elements;
let i = 0;
try {
do {
model = model.children.find(child => child.mStyle === modelStyles[i]);
i += 1;
} while (i < modelStyles.length);
return model;
} catch (e) {
return undefined;
}
};
tried this:
findModel = function(oldModel, ...modelStyles) {
let model = oldModel.elements;
let i = 0;
if (i < modelStyles.length) {
model = model.children.find(child => child.mStyle === modelStyles[i]);
i += 1;
return model;
} else {
return undefined;
}
};
but it's still not working well. in the first code I get only the element, in the second one I get also undefined.
What did I wrong?
As amply noted in comments, you are actually never calling the function recursively.
When it comes to "pretty", I would not go for recursion, but for reduce:
var findModel = function(oldModel, ...modelStyles) {
try {
return modelStyles.reduce((model, style) => model.children.find(child => child.mStyle === style), oldModel.elements);
} catch (e) {} // No need to explicitly return undefined. It is the default
};
If you really need recursion, then first realise that your function expects a first argument type that never occurs again. Only the toplevel model has an elements property, so you can only call this function for ... the top level of your hierarchy.
To make it work, you would need another function that takes the model type as it occurs in the children:
var findModel = function(oldModel, ...modelStyles) {
function recur(model, style, ...modelStyles) {
if (style === undefined) return model;
return recur(model.children.find(child => child.mStyle === style), ...modelStyles);
}
// Need to change the type of the first argument:
try {
return recur(oldModel.elements, ...modelStyles);
} catch (e) {}
};
If you would change the code where the function is called initially, you could of course pass mainmodel.elements instead of mainmodel, so that this type difference problem is resolved. If you can make that change, then the recursive function can become:
var findModel = function(model, style, ...modelStyles) {
if (style === undefined) return model;
try {
return recur(model.children.find(child => child.mStyle === style), ...modelStyles);
} catch (e) {}
};
Still, I would prefer the reduce variant.
The point of recursive function is to call themselves into themselves. In your case, you are calling the function once, but the function never call itself so it just go through once. I'm not sure of the context so I can't fix your code but i can give you an example of recursion.
Lets say we have an object with property. Some are string, some are number and some are objects. If you want to retrieve each key of this object you would need recursion, since you don't know how deep the object goes.
let objectToParse = {
id: 10,
title: 'test',
parent: {
id: 5,
title: 'parent',
someKey: 3,
parent: {
id: 1,
title: 'grand-parent',
parent: null,
someOtherkey: 43
}
}
};
function parseParentKey(object) {
let returnedKey = [];
let ObjectKeys = Object.keys(object);
for(let i = 0; i < ObjectKeys.length; i++) {
if(typeof object[ObjectKeys[i]] === "object" && object[ObjectKeys[i]] !== null) {
// we are calling the methode inside itself because
//the current property is an object.
returnedKey = returnedKey.concat(parseParentKey(object[ObjectKeys[i]]));
}
returnedKey.push(ObjectKeys[i]);
}
return returnedKey;
}
console.log(parseParentKey(objectToParse));
I know this does not answer your question but it gives you a hint on how to use recursion properly. If your first code works, I don't see why you would need to change it in the first place.

Trying to understand functor but did not understand what that code exactly doing

Following code add map method to function prototype so we are able to map our function, which basically composing map function with the result of mappable function. I understand that
Function.prototype.map = function (f) {
const g = this
return function () {
return f(g.apply(this, arguments))
}
}
But did not understand the following
const Box = x => ({
map: f => Box(f(x)),
fold: f => f(x),
inspect: () => `Box(${x})`
})
const nextCharForNumberString = str =>
Box(str)
.map(s => s.trim())
.map(s => new Number(s))
.map(s => s + 1)
.map(s => String.fromCharCode(s))
.fold(s => s.toLowerCase())
console.log(nextCharForNumberString(' 64 '));
Could you help me to understand that. Box is a function Box(x) and I am losing track after that.Why those parenthesis ( ({ })) and how that thing is working.
Thanks for your time and understanding,
By the way first code is taken from
https://medium.com/#dtinth/what-is-a-functor-dcf510b098b6
Second code is coming from egghead.io's functional javascript first lesson (it is a shame I just stuck in the first lesson)
It might help to inflate the code out of es6 syntax.
function Box(param) {
return {
map: function(fn) { return Box(fn(param)); },
fold: function(fn) { return fn(param) },
inspect: function() { return `Box(${param})`;
}
}
an example: let a = Box(1); returns the object from the Box function and gives you access to a.map, a.fold, or a.inspect
a.map takes a function as a parameter. let's say that function returned the value passed in plus 1
function myFunction(n) { return n + 1 };
you could call a.fold(myFunction) and the returned value would equal 2. This is because our initial param was 1, and our function takes that parameter as its argument and returns.
Basically fold applies whatever function to your param and returns it.
map is similar except that it returns Box(myFunction(1)) which returns a new Box object with a param + 1 since that's what our function mutated our param to.
inspect simply outputs a string that tells you what the current value of param is.
Overview:
function add1(n) { return n + 1 }
let a = Box(1); //param is 1.
a.fold(add1); //translates to add1(1);
a.map(add1); //translates to Box(add(1)), aka, Box(2)
a.inspect(); //translates to "Box(2)"

Can't return a value from map iteration in Javascript

I'm having problems when trying to return a value encountered from a .map using Javascript. There's my code:
function LineaDeSuccion() {
const carga = vm.cargaTotal / vm.numeroEvaporadores;
vm.succion.map(i => {
if (i.temperatura == vm.tempSel) {
const cargas = Object.keys(i).map(function(key) {
return i[key];
});
// I need to return this value in my function
return getKeyByValue(i, closest(cargas, carga));
}
// Obviously I can't do it because the value it's encapsulated into the map callback.
// How can I solve it?
return value;
});
}
One approach is to use Array.prototype.find to find the value you want in the array, then perform the transformation you need once you have it.
function LineaDeSuccion() {
const carga = vm.cargaTotal / vm.numeroEvaporadores;
const i = vm.succion.find(i => i.temperatura == vm.tempSel);
if (i === undefined) {
throw Error("can't find what I want in the array");
}
const cargas = Object.keys(i).map(function (key) {
return i[key];
});
return getKeyByValue(i, closest(cargas, carga));
}
Note that this approach will not iterate over the entire array but break out of the find loop immediately once a match is found. If there are several elements i in the array which satisfy the condition i.temperatura == vm.tempSel, this will return the first match, not the last.
If you want to return a value outside of your map, you'll have to set a variable that lives outside of your map, and then set that value within your map:
function LineaDeSuccion() {
const carga = vm.cargaTotal / vm.numeroEvaporadores;
let value = "defaultValue"; // default value
vm.succion.map(i => {
if (i.temperatura == vm.tempSel) {
const cargas = Object.keys(i).map(function(key) {
return i[key];
});
value = getKeyByValue(i, closest(cargas, carga)); // new set value
}
});
return value;
}

Data structure adding and removing items using constructor functions

Its the beginning of a data structure exercise and I am trying to write an add and remove function -its should be so simple and I don't get why its wrong?! Also the way to do it 8using a constructor function, prototype etc. must stay the way it is)
Any help much appreciated!
function Thestack () {
this.array=[];
}
Thestack.prototype.plus = function (i) {
this.array.push(i);
return this; // cannot be edited
};
Thestack.prototype.minus = function () {
this.array.pop();
};
var smallstack = new Thetack();
smallstack.plus(something); //followed by
smallstack.minus();
should return: something
your minus function does not have a return statement, so it just returns undefined by default
You could as in the add function return this so you can continue chaining of methods, return the element removed or return the length of the remaing array
// return this for chaining
Thestack.prototype.minus = function () {
this.data.pop();
return this;
};
// return the removed item
Thestack.prototype.minus = function () {
//edits the data array in place and returns the last element
return this.data.pop();
};
// return the length of the remaining array
Thestack.prototype.minus = function () {
this.data.pop();
return this.data.length;
};

Categories

Resources