How to specify function to collection.find() dynamically - javascript

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);
});

Related

DRY - Typescript. How can I use DRY principles to avoid duplication of these 2 getters

I know that below two getters are duplicates and could be consolidated and written in a better way. Could any one please help me come up with a way to consolidate these:-
isEqual here is a lodash library to compare two objects.
state in here is an injected state which I am picking the objects from.
public get isUpperModified(): boolean {
if (!this.isUpperAvailable) {
return false;
}
if (
(this.orders.upperPreference.type === '1' &&
this.state.fetchedData.upperPreference.type === '1') ||
(this.orders.upperPreference.type === 'UPPER' &&
this.state.fetchedData.upperPreference.type === 'UPPER')
) {
return false;
}
if (!isEqual(this.orders.upperPreference, this.state.fetchedData.upperPreference)) {
return true;
}
return false;
}
public get isLowerModified(): boolean {
if (!this.isLowerAvailable) {
return false;
}
if (
(this.orders.lowerPreference.type === '1' &&
this.state.fetchedData.lowerPreference.type === '1') ||
(this.orders.lowerPreference.type === 'LOWER' &&
this.state.fetchedData.lowerPreference.type === 'LOWER')
) {
return false;
}
if (!isEqual(this.orders.lowerPreference, this.state.fetchedData.lowerPreference)) {
return true;
}
return false;
}
There are more than 1 way to achieve this.
You can create a new function isModified(type: string) and pass upper or lower as an argument.
Hope this helps
public get isUpperModified(): boolean {
return this.isModified('upper');
}
public get isLowerModified(): boolean {
return this.isModified('lower');
}
private isModified(type: 'lower' | 'upper'): boolean {
const available = type === 'lower' ? this.isLowerAvailable : this.isUpperAvailable;
const order = type === 'lower' ? this.orders.lowerPreference : this.orders.upperPreference;
const state = type === 'lower' ? this.state.fetchedData.lowerPreference : this.state.fetchedData.upperPreference;
if (!available) {
return false;
}
if (
(order.type === '1' &&
state.type === '1') ||
(order.type === type.toUpperCase() &&
state.type === type.toUpperCase())
) {
return false;
}
if (!isEqual(order, state)) {
return true;
}
return false;
}
I would do it something like this
public get isModified(type: 'lower' | 'upper'): boolean {
const isAvailable = type === "lower" ? this.isLowerAvailable : this.isUpperAvailable
const preference = type === "lower" ? "lowerPreference" : "upperPreference";
if (!isAvailable) {
return false;
}
if (
(this.orders[preference].type === '1' &&
this.state.fetchedData[preference].type === '1') ||
(this.orders[preference].type === 'LOWER' &&
this.state.fetchedData[preference].type === 'LOWER')
) {
return false;
}
if (!isEqual(this.orders[preference], this.state.fetchedData[preference])) {
return true;
}
return false;
}
Then while calling this method
use isModified("upper") instead of isUpperModified
and
use isModified("lower") instead of isLowerModified

Why doesn't shouldComponentUpdate by default compare nextProps to the current one?

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?

javascript recursion find not returning

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);

Recursion Function to search

How would I go about creating a recursive function that can search through a list for a node where x = 10?
I do not have any javascript experience so I am not sure where to start so would appreciate and input
I have come across the following code and tried to adapt it but I am not sure if I am on the right track:
function search(_for, _in) {
var r;
for (var p in _in) {
if ( p === 10 ) {
return _in[p];
}
if ( typeof _in[p] === 'object' ) {
if ( (r = search(_for, _in[p])) !== null ) {
return r;
}
}
}
return null;
}
Thank you in advance
Try this
var finder = function(needle, haystack) {
if (haystack.length == 0)
return false
if (haystack[0] == needle)
return true
return finder(pin, haystack.slice(1))
}
Or
var finder = function(pin, haystack) {
return (haystack[0] == pin) || (haystack.length != 0) && finder(pin, haystack.slice(1))
}
Recursion FTW

SlickGrid- Need of insensitive case filter

Is there's a way to change the filter from sensitive case to insensitive?
Thank you.
Here’s the relevant section of a working example using the DataView filter. Notice the searchString variable is converted to lowercase when the value is first defined and then it's compared to lowercase strings within the myFilter function.
function myFilter(item, args) {
if (args.searchString != "" && item["FirstName"].toLowerCase().indexOf(args.searchString) == -1 && item["LastName"].toLowerCase().indexOf(args.searchString) == -1) {
return false;
}
return true;
}
....
$("#txtSearch").keyup(function (e) {
Slick.GlobalEditorLock.cancelCurrentEdit();
// clear on Esc
if (e.which == 27) {
this.value = "";
}
searchString = this.value.toLowerCase();
updateFilter();
});
function updateFilter() {
dataView.setFilterArgs({
searchString: searchString
});
dataView.refresh();
}
// initialize the model after all the events have been hooked up
dataView.beginUpdate();
dataView.setItems(data);
dataView.setFilterArgs({
searchString: searchString
});
dataView.setFilter(myFilter);
dataView.endUpdate();
Guessing you are talking about the DataView filter, the implementation of the filter functionality is totally up to you. Note the filter function used in the SlickGrid examples - that function is set as the filter using dataView.setFilter(your_function_here). So implement the filter function as you want and set it to the dataView
function filter(item) {
// String Should Match Each Other
/* for (var columnId in columnFilters) {
if (columnId !== undefined && columnFilters[columnId] !== "") {
var c = grid.getColumns()[grid.getColumnIndex(columnId)];
if (item[c.field] != columnFilters[columnId]) {
return false;
}
}
} */
for (var columnId in columnFilters) {
if (columnId !== undefined && columnFilters[columnId] !== "") {
var c = grid.getColumns()[grid.getColumnIndex(columnId)];
// This Case Sensitive
//if (!(item[c.field] && (""+item[c.field]).indexOf(columnFilters[columnId]) !== -1)) {
if (!(item[c.field] && (""+item[c.field].toLowerCase()).indexOf(columnFilters[columnId].toLowerCase()) !== -1)) {
// Case in-Sensitive
return false;
}
}
}
return true;
}

Categories

Resources