My problem is that a loop that is called in another for loop and should return an object does not return anything. When I set a breakpoint to the return statement the object is there but undefined in my callback function. types object is a global object that contains many objects as properties with the properties "title" and "id".
function searchObj(obj, query) {
for (var key in obj) {
var value = obj[key];
if (typeof value === 'object') {
searchObj(value, query)
}
if (value === query) {
return obj;
}
}
}
The function is called from here:
function callback(data){
var logs = [];
var results = data.d.results;
for (var i = 0; results.length; i++) {
var item = results[i];
var action = util.searchObj(types, item.ActionId);
var obj = {
'Created': item.Created,
'Text': String.format(action.title, item.Author.Title),
'Author': item.Author
}
logs.push(obj);
}
console.log(logs);
}
Try this:
function searchObj(obj, query) {
for (var key in obj) {
var value = obj[key];
if (typeof value === 'object') {
var result = searchObj(value, query);
if (result) {
return result;
}
}
if (value === query) {
return obj;
}
}
}
Related
I was making a HashTable to have as an example and have it saved for any problem, but I ran into a problem trying to implement a method that returns true or false in case the value belongs to the HashTable, since it is inside a arrays of objects as comment in the code.
I have tried for loops, .map and for of, but it always fails, if someone could help me.
function HashTable () {
this.buckets = [];
this.numbuckets = 35;
}
HashTable.prototype.hash = function (key) {
let suma = 0;
for (let i = 0; i < key.length; i++) {
suma = suma + key.charCodeAt(i);
}
return suma % this.numbuckets;
}
HashTable.prototype.set = function (key, value) {
if (typeof key !== "string") {
throw new TypeError ("Keys must be strings")
} else {
var index = this.hash(key);
if(this.buckets[index] === undefined) {
this.buckets[index] = {};
}
this.buckets[index][key] = value;
}
}
HashTable.prototype.get = function (key) {
var index = this.hash(key);
return this.buckets[index][key];
}
HashTable.prototype.hasKey = function (key) {
var index = this.hash(key);
return this.buckets[index].hasOwnProperty(key)
}
HashTable.prototype.remove = function (key) {
var index = this.hash(key);
if (this.buckets[index].hasOwnProperty(key)) {
delete this.buckets[index]
return true;
}
return false;
}
HashTable.prototype.hasValue = function (value) {
let result = this.buckets;
result = result.flat(Infinity);
return result // [{Name: Toni}, {Mame: Tino}, {Answer: Jhon}]
}
You can use Object.values() to get the values of all the propertyies in the bucket.
function HashTable() {
this.buckets = [];
this.numbuckets = 35;
}
HashTable.prototype.hash = function(key) {
let suma = 0;
for (let i = 0; i < key.length; i++) {
suma = suma + key.charCodeAt(i);
}
return suma % this.numbuckets;
}
HashTable.prototype.set = function(key, value) {
if (typeof key !== "string") {
throw new TypeError("Keys must be strings")
} else {
var index = this.hash(key);
if (this.buckets[index] === undefined) {
this.buckets[index] = {};
}
this.buckets[index][key] = value;
}
}
HashTable.prototype.get = function(key) {
var index = this.hash(key);
return this.buckets[index][key];
}
HashTable.prototype.hasKey = function(key) {
var index = this.hash(key);
return this.buckets[index].hasOwnProperty(key)
}
HashTable.prototype.remove = function(key) {
var index = this.hash(key);
if (this.buckets[index].hasOwnProperty(key)) {
delete this.buckets[index]
return true;
}
return false;
}
HashTable.prototype.hasValue = function(value) {
return this.buckets.some(bucket => Object.values(bucket).includes(value));
}
let h = new HashTable;
h.set("Abc", 1);
h.set("Def", 2);
console.log(h.hasValue(1));
console.log(h.hasValue(3));
I want to copy object from "xwalk.utils.converter" to "xwalk.converter"
the converter has these functions.
Is it available copy of object? otherwise alias?
xwalk.utils.converter.toArray
xwalk.utils.converter.toBoolean
xwalk.utils.converter.toByte
xwalk.utils.converter.toDictionary
xwalk.utils.converter.toDouble
xwalk.utils.converter.toEnum
xwalk.utils.converter.toFunction
xwalk.utils.converter.toLong
xwalk.utils.converter.toLongLong
xwalk.utils.converter.toOctet
xwalk.utils.converter.toPlatformObject
xwalk.utils.converter.toShort
xwalk.utils.converter.toUnsignedLong
xwalk.utils.converter.toUnsignedLongLong
xwalk.utils.converter.toUnsignedShort
Untested code, which recursively copies the elements:
function copy(src) {
var destination = {};
for (var index in src) {
if (typeof src[index] === "object") {
destination[index] = copy(src[index]);
} else if (Array.isArray(src[index])) {
destination[index] = [];
for (var arrIndex in src[index]) {
if ((typeof src[index][arrIndex] === "object") || (Array.isArray(src[index][arrIndex]))) {
destination[index][arrIndex] = copy(src[index][arrIndex]);
} else {
destination[index][arrIndex] = src[index];
}
}
} else {
destination[index] = src[index];
}
}
return destination;
}
Usage:
xwalk.converter = xwalk.utils.converter;
Use this function:
var copy = function(from, to) {
for (var prop in from) {
if (from.hasOwnProperty(prop)) {
to[prop] = from[prop];
}
}
};
copy(xwalk.utils.converter,xwalk.converter);
My application calls the module to parse nested JSON object, to read values of 2 keys.
parseData(str, function (error, str) {
if (err) {
console.log("Error - parseData : ", err);
} else {
console.log(str);
}
And the parseData module is as follows
function parseData(str, callback) {
function recursiveFunction(obj) {
var keysArray = Object.keys(obj);
for (var i = 0; i < keysArray.length; i++) {
var key = keysArray[i];
var value = obj[key];
if (value === Object(value)) {
parseData(value);
} else {
if (key == 'title') {
title = value;
}
if (key == 'extract') {
var extract = value.replace(/(\r\n|\n|\r)/gm," ");
callback(null, JSON.stringify('{"title":'+ title + ', "text":' + extract));
}
}
}
}
recursiveFunction(str);
}
But it shows following error
/modules/parseData.js:22
callback(null, JSON.stringify('{"title":'+ title + ', "text":' + extract));
^
TypeError: callback is not a function
Why is callback failing ? How to return back JSON object ?
EDIT
There were some errors in the code and now corrected.
function parseData(str, callback) {
function recursiveFunction(obj) {
var keysArray = Object.keys(obj);
for (var i = 0; i < keysArray.length; i++) {
var key = keysArray[i];
var value = obj[key];
if (value === Object(value)) {
recursiveFunction(value);
} else {
if (key == 'title') {
title = value;
}
if (key == 'extract') {
var extract = value.replace(/(\r\n|\n|\r)/gm," ");
callback(null, JSON.stringify('{"title":'+ title + ', "text":' + extract));
}
}
}
}
recursiveFunction(str);
};
You're calling parseData(value); and not passing a callback; pass callback if you want that original callback to be used.
I try to create a validation function to validate some dynamic forms. But i got a problem... I'm trying to search into an object for some properties with their values.
There's my code:
export default function(form) {
return (values) => {
const errors = {};
Object.keys(values).forEach((key) => {
let result = searchIn(form, 'name', key); // undefined
});
function searchIn(obj, prop, value) {
Object.keys(obj).forEach(function(key, i) {
if(key !== prop){
if(typeof obj[key] === "object"){
searchIn(obj[key], prop, value);
}
}else{
if(obj[key] === value){
return obj; // [object]
}
}
});
}
return errors;
}
};
In the Object.keys(values).map loop, it logs undefined, but just before that, at return obj; // [object] it log the object correctly. How can i make it work correctly? I don't understand how it doesn't return the object found in the searchIn function.
Thank you
I reformated all my code for this and it works.
export default function(form) {
return (values) => {
const errors = {};
Object.keys(values).forEach((key) => {
let result = searchIn(form, 'name', key); // undefined
console.log(result);
});
function searchIn(obj, prop, value) {
let keys = Object.keys(obj);
for(let i = 0; i <= keys.length; i++){
let key = keys[i];
if(key !== prop){
if(typeof obj[key] === 'object'){
let result = searchIn(obj[key], prop, value);
if(result !== false){
return result;
}
}else{
if(obj[key] === value){
return obj;
}
}
}
}
return false;
}
return errors;
}
};
I have a JSON OBJECT similar to following
{
"kay1":"value1",
"key2":"value2",
"key3":{
"key31":"value31",
"key32":"value32",
"key33":"value33"
}
}
I want to replace that with JSON ARRAY as follows
[
"value1",
"value2",
[
"value31",
"value32",
"value33"
]
]
My motivation to change the the JSON OBJECT to JSON ARRAY is it takes less amount of network traffic, getting the value from ARRAY is efficient than OBJECT, etc.
One problem I face is the readability of the ARRAY is very less than OBJECT.
Is there any way to improve the readability?
Here you go, I have written a function which will convert all instances of object to array and give you the result you are expecting.
var objActual = {
"key1":"value1",
"key2":"value2",
"key3":{
"key31":"value31",
"key32":"value32",
"key33": {
"key331" : "value331",
"key332" : "value332"
}
}
};
ObjectUtil = {
isObject : function(variable) {
if(Object.prototype.toString.call(variable) === '[object Object]') {
return true;
}
return false;
},
convertToArray : function(obj) {
var objkeys = Object.keys(obj);
var arr = [];
objkeys.forEach(function(key) {
var objectToPush;
if(ObjectUtil.isObject(obj[key])) {
objectToPush = ObjectUtil.convertToArray(obj[key]);
} else {
objectToPush = obj[key];
}
arr.push(objectToPush);
});
return arr;
}
};
var result = ObjectUtil.convertToArray(objActual);
console.log(result);
In my opinion, it should be:
{
"kay1":"value1",
"key2":"value2",
"key3":["value31", "value32", "value33"]
}
Using the init method is time critical. So use a scheme or assign static JSON to Storage.keys and assign your bulk data array to store.data. You can use store.get("key3.key31") after that. http://jsfiddle.net/2o411k00/
if (!Array.prototype.map)
{
Array.prototype.map = function(fun /*, thisp*/)
{
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var res = new Array(len);
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this)
res[i] = fun.call(thisp, this[i], i, this);
}
return res;
};
}
var data = {
"kay1":"value1",
"key2":"value2",
"key3":{
"key31":"value31",
"key32":"value32",
"key33":"value33"
}
}
var Storage = function(data){
this.rawData = data;
return this;
}
Storage.prototype.init = function(){
var self = this;
var index = 0;
var mp = function(dat, rootKey){
var res = Object.keys(dat).map(function(key, i) {
var v = dat[key];
if (typeof(v) === 'object'){
mp(v, key);
} else {
self.data.push(v);
var nspace = rootKey.split(".").concat([key]).join(".");
self.keys[nspace] = index++;
}
});
}
mp(this.rawData, "");
}
Storage.prototype.get = function(key){
return this.data[this.keys[key]];
};
Storage.prototype.data = [];
Storage.prototype.keys = {};
var store = new Storage(data);
console.log(data);
store.init();
console.log("keys", store.keys);
console.log("data", store.data);
console.log("kay1=", store.get(".kay1"));
console.log("key2=", store.get(".key2"));
console.log("key3.key31=", store.get("key3.key31"));
console.log("key3.key32=",store.get("key3.key32"));
console.log("key3.key33=", store.get("key3.key33"));