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);
Related
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 using a category Array namely CategoryListSearch which contains various categories like Mobile electronics, jewellery etc.
I am using a text box In that text box i am inserting a value like IPhone so how can i match from the list that I phone belongs to category mobile.
I am using this as a sample
if (txt != '') {
$.each(CategoryListSearch, function(i, o) {
});
but don't know that how to compare text value from CategoryListSearch.
please help!
Try this
if(CategoryListSearch.indexOf(text) > -1) {
//text is present
}
Like this.use ternary operator(?:) inside loop.
if (txt != '') {
$.each(CategoryListSearch, function(i, o) {
var present = (o == txt) ? "Item present in list" : "No item in list";
console.log(present);
}
});
Assuming that your object is of tree-structure the following function first checks whether we are searching for the object itself. If not, then it is iterated and we search for the index/member.
getCategoryPath(obj, item) {
if (obj === item) {
return obj;
}
for (index in obj) {
if ((typeof obj[index] === "undefined") || (obj[index] === null)) {
//irrelevant leaf
} else if (typeof obj[index] === "object") {
var ret = getCategoryPath(obj[index], item);
if (ret) {
return ret.unshift(index);
}
} else if ((obj[index] === item) || (index === item)) {
return [index];
}
}
}
How can I pass the function logic to the find-function in order to use it on each document?
I am trying to find Mongo-documents recursively with certain values in a property. I have defined an "algorithm" and would like to this to the find-function, but despite reading about queries, searching and find(), I have had no luck.
// match every node with propertyname "Reference" with the exact value "43_1"
var logic = function(currentKey, currentValue) {
return ( currentKey == "Reference" && currentValue === "43_1" );
};
db.getCollection('metavalg').find(function() {
function recurSearchObj(doc) {
return Object.keys(doc).some(function(key) {
if ( typeof(doc[key]) == "object" && doc[key] !== null ) {
return recurSearchObj(doc[key]);
} else {
// invoke matching-logic
return logic(key, doc[key]);
}
});
}
// search document recursively
return recurSearchObj(this);
})
With the help of Vladimir M, I ended up rearringing the code and doing this:
db.getCollection('metavalg').find(function() {
function inspectObj(doc, logic) {
return Object.keys(doc).some(function(key) {
if ( typeof(doc[key]) == "object" && doc[key] !== null ) {
return inspectObj(doc[key], logic);
} else {
return logic(key, doc[key]);
}
});
}
return inspectObj(this, function(currentKey, currentValue) {
return ( currentKey == "Nummer" && currentValue === "43_1" );
//return ( currentKey == "Navn" && /max\.? 36/i.test(currentValue) );
});
})
You can pass logic method as a parameter to recurcive search object:
// match every node with propertyname "Reference" with the exact value "43_1"
var logic = function(currentKey, currentValue) {
return ( currentKey == "Reference" && currentValue === "43_1" );
};
db.getCollection('metavalg').find(function() {
function recurSearchObj(doc, aLogic) {
return Object.keys(doc).some(function(key) {
if ( typeof(doc[key]) == "object" && doc[key] !== null ) {
return recurSearchObj(doc[key], aLogic);
} else {
// invoke matching-logic
if( aLogic(key, doc[key]) ){
// then do somthing
}
}
});
}
// search document recursively
return recurSearchObj(this, logic);
});
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().
I'm using the code below and It's working good, but when I try to use JQuery at the same time, then I'm getting the below error, I was reading some posts and I think the problem is that no is possible extend the Object.prototype without checking hasOwnProperty(), but I don't know how to solve that, can someone give me a hand?
Code:
Object.prototype.clone = function () {
var i, newObj = (this instanceof Array) ? [] : {};
for (i in this) {
if (i === 'clone') {
continue;
}
if (this[i] && typeof this[i] === "object") {
newObj[i] = this[i].clone();
} else {
newObj[i] = this[i];
}
}
return newObj;
};
Error:
Uncaught TypeError: Object function () {
var i, newObj = (this instanceof Array) ? [] : {};
for (i in this) {
if (i === 'clone') {
continue;
}
if (this[i] && typeof this[i] === "object") {
newObj[i] = this[i].clone();
} else {
newObj[i] = this[i];
}
}
return newObj;
} has no method 'exec'
Add the following function to your clone object:
Object.prototype.clone.exec=function() {
//your codes
};