i have a problem with a mongoDb query, i need to search for a parameter value of any MongoDB field.
I use a function in $where clause like:
db.response.find(
{
$where: function() {
var deepIterate = function (obj, value) {
for (var field in obj) {
if (obj[field] == value){
return true;
}
var found = false;
if ( typeof obj[field] === ‘object’) {
found = deepIterate(obj[field], value)
if (found) { return true; }
}
}
return false;
};
return deepIterate(this, “Text36")
}
});
The returned response was fine but I don't know how I can pass the value (Text36 in this sample) I want to found like a parameter
can someone help me please ? Thanks
I've searched and searched but cannot find a better way to search through a JSON object and return a nested object that corresponds to a specific key.
I've found examples that work in javascript but when I try to use that code in Google Apps Script I find that some of the function/modules are not supported.
deeply The script below works where objRet is a global variable but I wondered if there was a better way to do it?
var objRet;
function blahblah() {
traverse(api_info, "EarningsRates");
// use this.objRet to process code
}
function traverse(json, keyData) {
var keyData = keyData;
var json = json;
if (Array.isArray(json)) {
json.forEach(traverse);
} else if (typeof json === 'object') {
Object.keys(json).forEach(function(key) {
if (key === keyData) {
this.retObj = json[key];
} else {
traverse(json[key], keyData);
}
});
}
}
I found this and would love to get it working but no luck with Google Apps Script
This function implements DFS: (depth first search)
function findDFS(objects, id) {
for (let o of objects || []) {
if (o.uuid == id) return o
const o_ = findDFS(o.children, id)
if (o_) return o_
}
}
And BFS:(breadth first search)
function findBFS(objects, id) {
const queue = [...objects]
while (queue.length) {
const o = queue.shift()
if (o.uuid == id) return o
queue.push(...(o.children || []))
}
}
I am using node.js and as a side project i am creating a module that reads a .json file ,parse it then create directory structure based on object properties & object values.
Object properties(keys) would be the path to itself/to files & object values would be the list of files for that path
i have tried to recurse downwards through the object but i dont know how i extract the path from the inner-most object of each object
Also object would be dynamic as would be created by the user.
var path = 'c:/templates/<angular-app>';
var template = {
//outline of 'angular-app'
src:{
jade:['main.jade'],
scripts:{
modules:{
render:['index.js'],
winodws:['index.js'],
header:['header.js' ,'controller.js'],
SCSS:['index.scss' ,'setup.scss'],
}
}
},
compiled:['angular.js','angular-material.js' ,'fallback.js'],
built:{
frontEnd:[],//if the array is empty then create the path anyways
backEnd:[],
assets:{
fontAwesome:['font-awesome.css'],
img:[],
svg:[]
}
}
}
//desired result...
let out = [
'c:/template name/src/jade/main.jade',
'c:/template name/src/scripts/index.js',
'c:/template name/src/scripts/modules/render/index.js',
'c:/template name/compiled/angular.js',
'c:/template name/compiled/angular-material.js',
'c:/template name/compiled/fallback.js',
'c:/template name/built/frontEnd/',
'c:/template name/built/backEnd/',
//...ect...
];
Here's an example on how you can write this recursively:
var path = 'c:/templates';
var template = {
//outline of 'angular-app'
src: {
jade: ['main.jade'],
scripts: {
modules: {
render: ['index.js'],
winodws: ['index.js'],
header: ['header.js', 'controller.js'],
SCSS: ['index.scss', 'setup.scss'],
}
}
},
compiled: ['angular.js', 'angular-material.js', 'fallback.js'],
built: {
frontEnd: [], //if the array is empty then create the path anyways
backEnd: [],
assets: {
fontAwesome: ['font-awesome.css'],
img: [],
svg: []
}
}
}
function recurse(item, path, result) {
//create default output if not passed-in
result = result || [];
//item is an object, iterate its properties
for (let key in item) {
let value = item[key];
let newPath = path + "/" + key;
if (typeof value === "string") {
//if the property is a string, just append to the result
result.push(newPath + "/" + value);
} else if (Array.isArray(value)) {
//if an array
if (value.length === 0) {
//just the directory name
result.push(newPath + "/");
} else {
//itearate all files
value.forEach(function(arrayItem) {
result.push(newPath + "/" + arrayItem);
});
}
} else {
//this is an object, recursively build results
recurse(value, newPath, result);
}
}
return result;
}
var output = recurse(template, path);
console.log(output);
My solution for this problem would be as follows;
function getPaths(o, root = "", result = []) {
var ok = Object.keys(o);
return ok.reduce((a,k) => { var p = root + k + "/";
typeof o[k] == "object" && o[k] !== null &&
Array.isArray(o[k]) ? o[k].length ? o[k].forEach(f => a.push(p+=f))
: a.push(p)
: getPaths(o[k],p,a);
return a;
},result);
}
var path = 'c:/templates/',
template = {
//outline of 'angular-app'
src:{
jade:['main.jade'],
scripts:{
modules:{
render:['index.js'],
winodws:['index.js'],
header:['header.js' ,'controller.js'],
SCSS:['index.scss' ,'setup.scss'],
}
}
},
compiled:['angular.js','angular-material.js' ,'fallback.js'],
built:{
frontEnd:[],//if the array is empty then create the path anyways
backEnd:[],
assets:{
fontAwesome:['font-awesome.css'],
img:[],
svg:[]
}
}
},
paths = getPaths(template,path);
console.log(paths);
It's just one simple function called getPaths Actually it has a pretty basic recursive run. If your object is well structured (do not include any properties other than objects and arrays and no null values) you may even drop the typeof o[k] == "object" && o[k] !== null && line too. Sorry for my unorthodox indenting style but this is how i find to deal with the code more easy when doing ternaries, logical shortcuts and array methods with ES6 arrow callbacks.
I am making a json after watching a json object ,But I am getting more key or text .I need to remove that text.
I am getting this output
function mapItem(inputItem) {
var item = {};
item[inputItem.id] = JSON.parse(sessionStorage.getItem(inputItem.id));
for (k in inputItem.children) {
if (/^not-/.test(inputItem.children[k].id)) {
item[inputItem.id].commandList.push(mapItem(inputItem.children[k]));
}else{
item[inputItem.id].testCaseList.push(mapItem(inputItem.children[k]));
}
}
return item;
}
http://jsfiddle.net/tJ7Kq/7/
I THINK PROBLEM ON THIS LINE
item[inputItem.id].commandList.push(mapItem(inputItem.children[k]));
Try this.
http://jsfiddle.net/tJ7Kq/8/
function mapItem(inputItem) {
//var item = {};
var item = JSON.parse(sessionStorage.getItem(inputItem.id));
for (k in inputItem.children) {
if (/^not-/.test(inputItem.children[k].id)) {
item.commandList.push(mapItem(inputItem.children[k]));
}else{
item.testCaseList.push(mapItem(inputItem.children[k]));
}
}
return item;
}
I need to search a complex json object recursively, and delete the object associated with any key that starts with "_".
So far, I have:
sanitize: function(json){
for(var i in json){
if(json[i]){
if(i.substring(0,1) == "_")
delete json[i];
else
this.sanitize(json[i]);
}
}
console.log(json);
return json;
}
I exceed the maximum call stack.
Try using your own array, and also make sure the subobjects aren't circular references, and also make sure they're objects.
function sanitize(json) {
var stack = [];
var done = [];
do {
for(var x in json) {
if(x.charAt(0) === '_') {
delete json[x];
} else if(done.indexOf(json[x]) === -1 && typeof json[x] === 'object') {
stack.push(json[x]);
done.push(json[x]);
}
}
} while(json = stack.pop());
}