I have a function like so:
function contains(needle,haystack) {
return $.each(haystack,function(i,v) {
if(v == needle) {
console.log('true, so return');
return true;
}
if(typeof v == 'object') {
return app.contains(needle,v);
}
console.log('I have not yet returned');
return false;
});
}
When I pass something into it (let's say an object of length 2, with one item matching) the console shows:
true, so return
I have not yet returned
I have not yet returned
Why is this? How do I fix it?
Returning true/undefined from the each callback will continue executing the next iteration.
What you need to do is to use a flag and if a match is found then set the flag to true and return false so that rest of the iterations will be ignored
function contains(needle, haystack) {
var result = false;
$.each(haystack, function (i, v) {
if (v == needle) {
console.log('true, so return');
result = true;
return false;
}
if (typeof v == 'object') {
if (app.contains(needle, v)) {
result = true;
return false;
}
}
console.log('I have not yet returned');
});
return result;
}
It is because you return only from inner function of each $.each iteration.
To break $.each loop you need return false, so return !result will return false if and only if result if found
function contains(needle,haystack) {
var result = false;
$.each(haystack,function(i,v) {
if(v == needle) {
result = true;
return !result;
}
if(typeof v == 'object') {
result = contains(needle,v);
return !result;
}
});
return result;
}
http://jsfiddle.net/8dggq7ds/2/
Or shorter version
function contains(needle,haystack) {
var result = false;
$.each(haystack,function(i,v) {
return !(result = (typeof v === 'object') ? contains(needle,v) : v == needle);
});
return result;
}
Moreover, recursion call app.contains() change to contains().
Related
I have added these functions and need return something based which function is returning true but it is not working.
//this is function1/
function A() {
return true;
}
function B() {
return true;
}
function C() {
if ({
{
var -customJS - page_type_lookup
}
} === 'product') {
var config = document.querySelector('#product-content > div.product-variations.clearfix > div.attribute.variant-dropdown > div.attribute-values-section > div.label.va-navSectionalOrientation').innerText;
if (config.includes('Sectional Orientation')) {
return true;
} else {
return false;
}
}
}
if (A() === true && B() === true && C() === true) {
return 'A+ Content, RTA Product, Sectional Configurator';
} else if (A() === true && B() === true) {
return 'A+ Content, RTA Product';
} else if (B() === true && C() === true) {
return 'RTA Product, Sectional Configurator';
} else if (C() === true && A() === true) {
return 'Sectional Configurator, A+ Content';
} else if (A() === true) {
return 'A+ Content';
} else if (B() === true) {
return 'RTA Product';
} else {
return 'Sectional Configurator';
}
}
If you have more than one function and a data set which reflects the wanted value of each flag, you could take an array for the functions retun values and another for the strings which are filterd and joined for the result.
const
flags = [a(), b(), c()],
result = ['A+ Content', 'RTA Product', 'Sectional Configurator']
.filter((_, i) => flags[i])
.join(', ');
I have this case:
function f1(a) {
a = f2(a);
// do some other stuff
console.log("I don't want the function f1 to log this.")
}
function f2(a) {
if (a == null) {
console.log("enters here")
return;
}
return a;
}
f1(null)
if a is null, I don't want f1 to continue with the console.log(). What can I change to obtain this behavior? (I know I can do this with some booleans but I was wondering if there is another way to solve this)
You could store the last value of a and exit if temp is null.
function f1(a) {
let temp = a;
a = f2(a);
// do some other stuff
if (temp === null) return;
console.log("I don't want the function f1 to log this.");
}
function f2(a) {
if (a == null) {
console.log("enters here");
return;
}
return a;
}
f1(null);
if a is null, I don't want f1 to continue with the console.log()
In that case you have to test the value of a within the f1 function:
function f1(a) {
a = f2(a);
// do some other stuff
if (a == null) return;
console.log("I don't want the function f1 to log this.")
}
function f2(a) {
if (a == null) {
console.log("enters here")
return;
}
return a;
}
f1(null)
just return false
function f1(a) {
a = f2(a);
// do some other stuff
if (!a) return
console.log("I don't want the function f1 to log this.")
}
function f2(a) {
if (a == null) {
console.log("enters here")
return false;
}
return a;
}
f1(null)
I'm wondering why shouldComponentUpdate by default does return true when it seems to me like the 1 and only reason not to re-render is if nextProps and this.props are "equal" in the sense of a deep comparison like
function shouldWeRender(prev, next)
{
return !objectsEqual(prev, next);
}
function objectsEqual(a, b)
{
var ta = typeof(a), tb = typeof(b);
if(ta !== 'object' || tb !== 'object') {
throw 'Arguments must be objects';
}
var ka = _.keys(a), kb = _.keys(b);
if(ka.length !== kb.length) {
return false;
}
_.forEach(ka, function(key) {
if(!b[key]) {
return false;
}
else if(typeof(a[key] === 'object') && !objectsEqual(a[key], b[key])) {
return false;
}
else if(a[key] !== b[key]) {
return false;
}
});
return true;
}
Shouldn't that be able to work as universal condition for rendering, assuming that we are using stateless components as is proper?
I am trying to write a function to search through an object for an element and return its parent array. This code looks like it should work, but it only returns undefined, can someone explain why?
findInArray = function(el, obj) {
if(Array.isArray(obj)){
obj.forEach(function(element) {
if(element === el) {
return obj;
} else if (typeof element === 'object' && obj) {
return findInArray(el, element);
}
})
} else if(typeof obj === 'object' && obj) {
for(prop in obj) {
if(typeof obj[prop] === 'object' && obj) {
return findInArray(el, obj[prop]);
}
}
}
}
You are not returning from the first if block:
if(Array.isArray(obj)){
obj.forEach(...)
}
hence the function returns undefined. If you want to return the value that the callback returns, you have to restructure your code.
It seems Array#reduce would be appropriate here:
return obj.reduce(function(result, element) {
if (result) {
return result;
}
if(element === el) {
return obj;
}
if (typeof element === 'object' && obj) {
return findInArray(el, element);
}
}, null);
This question already has answers here:
Return value from callback function
(2 answers)
Closed 9 years ago.
My function here is ever returnig undefined, what is wrong?
function getTaxType() {
$('.type').each(function() {
if ($(this).data('tax') === 'form1' && $(this).is(':checked')) {
return 'form1';
}
else if ($(this).data('tax') === 'form2' && $(this).is(':checked')) {
return 'form2';
}
else if ($(this).data('tax') === 'form3' && $(this).is(':checked')) {
return 'form3';
}
});
}
That's because you're returning from the callback function of $.each and not from getTaxType.
Try this:
function getTaxType() {
var result;
$('.type').each(function() {
if ($(this).data('tax') === 'form1' && $(this).is(':checked')) {
result = 'form1';
}
else if ($(this).data('tax') === 'form2' && $(this).is(':checked')) {
result = 'form2';
}
else if ($(this).data('tax') === 'form3' && $(this).is(':checked')) {
result = 'form3';
}
});
return result;
}
If it's checkboxes there can be more than one which means you have multiple results - storing this in array for you.
Multiple-Choice:
function getTaxType() {
var result = [];
$('.type:checked').each(function(i) {
var tax = $(this).data('tax');
result[i] = (tax === 'form1' || tax === 'form2' || tax === 'form3') ? tax : false;
});
return result;
};
If you meant to only have one result (radio button), then you remove the = [] on result and the [i] in the loop.
Single Answer
function getTaxType() {
var tax = $('.type:checked').data('tax');
var result = (tax === 'form1' || tax === 'form2' || tax === 'form3') ? tax : false;
return result;
};
Of course, if it is single answer (aka radio buttons) then you can ONLY have those three form answers which makes it even simpler:
function getTaxType() {
return $('.type:checked').data('tax');
};