I'm trying to know if there is a true or false reading on a substance from a dataset.
The dataset is something like this (being var drugs for l of 0),
{Caffeine: "{"drug":"Caffeine","dose":10,"amount":0}", Ritalin: "{"drug":"Ritalin","dose":"15","amount":1}"}
The algorithm i'm using in javascript is something like this currently.
var results = JSON.parse(overall[l].testdetails.result)
var drugs = overall[l].testdetails.drug
let substances = false
if (drugs != null) {
console.log("drugs: ",drugs)
for (var d = 0; d < drugs.length; d++ ){
var keyValue=Object.keys(drugs[d])
console.log("drug: ",drugs.keyValue)
if(JSON.parse(drugs.d.amount) !=0) {
substances=true
break
}
// console.log("drugs amount: ",JSON.parse(drugs[d].amount))
}
}
For some reason I am just unable to do a console log, or parse at all, this dataset.
What am i doing wrong here?
From what I can see it would be easier to iterate the drugs list if it was an array. That side, be aware if your data is a string or an object. In your code I got a bit confused about that.
String:
var drugsStr = '{"Caffeine":{"drug":"Caffeine","dose":10,"amount":0}, "Ritalin": {"drug":"Ritalin","dose":"15","amount":1}}';
var drugs = JSON.parse(drugsStr);
console.log(drugs);
Object:
var drugs = {Caffeine: {drug:"Caffeine",dose:10,"amount":0}, Ritalin: {drug:"Ritalin",dose:"15",amount:1}};
So, here is the solution with an object (drugs):
var drugs = {Caffeine: {drug:"Caffeine",dose:10,"amount":0}, Ritalin: {drug:"Ritalin",dose:"15",amount:1}};
var keys = Object.keys(drugs);
keys.forEach(key => {
console.log(drugs[key].drug);
console.log("drugs amount:", drugs[key].amount);
});
Your Json is formatted incorrectly.
let drugs = {
"Caffeine": {
"drug":"Caffeine",
"dose":10,
"amount":0
},
"Ritalin" : {
"drug":"Ritalin",
"dose":"15",
"amount":1
}
}
for (const [key, value] of Object.entries(drugs)) {
if(value['amount'] > 0 ) {
console.log( 'Positive for ' + key )
} else {
console.log( 'Negative for ' + key )
}
}
Related
I need to develop a Javascript function that can convert JSON format as the following. I am not sure if there is already a javascript function for this purpose or should i develop a new one on my own
Input: (example)
{
"event[id]": "1476258193",
"event[creator]": "aziz",
"event[title]": "event[title]",
"event[review][thankyou]": "event[review][thankyou]",
"event[review][teaser]": "event[review][teaser]"
}
The Output should be something like that:
{
Events: {
Id: “1476258193”,
Creator: “aziz”
…..
Review: {
Thankyou: “”,
Teaser: “”
}
}
}
EDIT (SOLUTION) : After some work and help from other users especially "anied" i did the function myself, if some one is interested here is a plunker with the answer, the function is not 100% optimal but it does what should do
https://plnkr.co/edit/4d6cDzHXpN3RAOAJD2F0?p=preview
convert = function() {
var obj = {
"event[id]": "1476258193",
"event[creator]": "smista",
"event[title]": "event[title]",
"event[crmid]": "event[crmid]",
"event[responsible]": "event[responsible]",
"event[location]": "event[location]",
"event[ktr]": "event[ktr]",
"event[description]": "event[description]",
"event[targetgroup]": "event[targetgroup]",
"event[learninggoals]": "event[learninggoals]",
"event[status]": "offline",
"event[issuu][html]": "event[issuu][html]",
"event[group_by_threads]": "1",
"event[timeblocks][0][lectures][0][persons][0]": "2",
"event[timeblocks][0][lectures][0][persons][1]": "333333",
"event[timeblocks][0][lectures][0][persons][2]": "3",
"event[timeblocks][0][lectures][1][persons][0]": "44",
"event[timeblocks][0][lectures][1][persons][1]": "444",
"event[timeblocks][0][lectures][1][persons][2]": "4444",
"event[participants]": "event[participants]",
"event[review][thankyou]": "event[review][thankyou]",
"event[review][teaser]": "event[review][teaser]"
}
var result = "Events : {";
var mainKeyString = "" ;
var mainKeys = [] ;
var keysCount = 0 ;
for (var k in obj) {
if( obj.hasOwnProperty(k) ) {
res = k.replace('event[', '');
mainKeyString+= res ;
}
}
mainKeyString = mainKeyString.replace(/\[/g,',');
mainKeyString = mainKeyString.replace(/\]/g,',');
mainKeyString = mainKeyString.replace(/,,/g,',');
mainKeyString = mainKeyString.substring(0, mainKeyString.length-1);
mainKeys = mainKeyString.split(',') ;
for (var i in obj) {
if( obj.hasOwnProperty(i) ) {
keysCount = (i.match(/\[/g) || []).length;
var lastKey = keysCount -1 ;
for (j=0;j<keysCount;j++){
if (keysCount >1 && j != lastKey){
result += mainKeys[0] +": {";
}
else if (keysCount >1 && j == lastKey) {
result += mainKeys[0] +":\""+obj[i] + "\"}";
}
else result += mainKeys[0] +":\""+obj[i] + "\",";
mainKeys.shift() ;
}
}
}
document.getElementById("result").innerHTML = result;
}
You should develop something because I don't know that anything like that exists. You will want to write a recursive method that iterates over the object keys and adds properties to a new source object. However, one difficulty will be that you will also need to handle duplicates (of which I see a few). If you can be confident of the format of the keys (that they only contain brackets to denote new properties), then you can write something that iterates over the keys in the object using a for...in loop (for key in yourobject) and looks for substr(key.indexOf('['), key.indexOf(']') to hunt down the logical delineations. Good luck!
I have an algorithm where the user will enter a string and I will parse it into an array of 2+ dimensions. So, for example, the user can enter 1,2,3;4,5,6 and set the text to be parsed by the semicolon and the comma. The first pass through will create an array with 2 entries. The second pass through will create a 3 entry array in both prior spots.
The user can add or remove the number of text items to be used to parse the original string such as the semicolon or comma, meaning the resulting array can have as many dimensions as parsing items.
This doesn't seem like a difficult problem, but I have run into some snags.
Here is my code so far.
vm.parsers = [';', ','];
vm.inputString = "1,2,3,4,5;6,7,8,9,10";
function parseDatasetText( )
{
vm.real = vm.parseMe( vm.inputString, 0);
};
function parseMe( itemToParse, indexToParse )
{
if ( indexToParse < vm.parsers.length )
{
console.log('Parsing *'+itemToParse+'* with '+vm.parsers[indexToParse]);
var tempResults = itemToParse.split( vm.parsers[indexToParse] );
for (var a=0; a<tempResults.length; a++)
{
console.log('Pushing '+tempResults[a]);
tempResults[a] = vm.parseMe( tempResults[a], parseInt( indexToParse ) + 1 )
console.log('This value is '+tempResults[a]);
}
}else
{
console.log('Returning '+itemToParse);
return itemToParse
}
};
As you can see from the console logs, the algorithm spits out an undefined after the last parse, and the final answer is undefined.
Maybe I just haven't slept enough, but I was thinking that the array would recursively populate via the splits?
Thanks
function parseDatasetText(){
//composing parser from right to left into a single function
//that applies them from left to right on the data
var fn = vm.parsers.reduceRight(
(nextFn, delimiter) => v => String(v).split(delimiter).map(nextFn),
v => v
);
return fn( vm.inputString );
}
Don't know what else to add.
You can use a simple recursive function like the following (here an example with 3 different delimiters):
function multiSplit(xs, delimiters) {
if (!delimiters.length) return xs;
return xs.split(delimiters[0]).map(x => multiSplit(x, delimiters.slice(1)));
}
data = '1:10,2:20,3:30;4:40,5:50,6:60';
res = multiSplit(data, [';', ',', ':']);
console.log(res)
The following function should suit your requirements, please let me know if not
var parsers = [';', ',', ':'],
inputString = "1:a,2:b,3:c,4:d,5:e;6:f,7:g,8:h,9:i,10:j",
Result = [];
function Split(incoming) {
var temp = null;
for (var i = 0; i < parsers.length; i++)
if (incoming.indexOf(parsers[i]) >= 0) {
temp = incoming.split(parsers[i]);
break;
}
if (temp == null) return incoming;
var outgoing = [];
for (var i = 0; i < temp.length; i++)
outgoing[outgoing.length] = Split(temp[i])
return outgoing;
}
Result = Split(inputString);
try it on https://jsfiddle.net/cgy7nre1/
Edit 1 -
Added another inputString and another set of parsers: https://jsfiddle.net/cgy7nre1/1/
Did you mean this?
var inputString = "1,2,3,4,5;6,7,8,9,10";
var array=inputString.split(';');
for (var i=0;i<array.length;i++){
array[i]=array[i].split(',');
}
console.log(array);
I am retrieving values from server side using ajax call and here is the formate of the arraylist retrieved from server side..
[INCOMING,0,INETCALL,0,ISD,31.8,LOCAL,197.92,STD,73.2]
Now as per my need i have to break this arraylist in two variables like this..
var toc=INCOMING,INETCALL,ISD,LOCAL,STD
var callcost=0,0,31.8,197.92,73.2
I am trying to do it using for loop but i am not getting exact logic...
Here is my code..
$(function () {
$.ajax({
type: 'GET',
url: 'getdata',
async: false,
dataType: "text",
success: function (data) {
var values = [];
values = data;
values = values.replace('[', '');
values = values.replace(']', '');
var array = values.split(",");
for (var i in array) {
}
}
});
});
Please guys help me .
Thanks in advance.
Try to use $.isNumeric() like,
var arr=['INCOMING',0,'INETCALL',0,'ISD',31.8,'LOCAL',197.92,'STD',73.2];
var str=[],
num=[];
for(var i=0,len=arr.length;i<len;i++){
$.isNumeric(arr[i]) ? num.push(arr[i]) : str.push(arr[i]);
}
console.log(num);// returns array of numbers use num.join(',') to get string
console.log(str);// returns array of string use str.join(',') to get string
Demo
First off, the data seems to be an array already, just parse it with
var array = JSON.parse(data);
Or, if you have control over the server-side code too, make it return json-data instead of plain text. That way its a array ready to use when its passed into the callback!
If you want to get all numeric in the loop, use isNumeric, if its every other, do a %1 on the index, ie:
var a1 = [];
var a2 = [];
for(var i=0;i<array.length;i++){
if(i % 1 == 0){
a1.push(array[i]);
} else {
a2.push(array[i]);
}
}
check this fiddle http://jsfiddle.net/2sGjZ/
var myArray = ['INCOMING','0','INETCALL','0','ISD','31.8','LOCAL','197.92','STD','73.2'];
var tocArr = new Array();
var callcostArr = new Array();
var j = 0; var k= 0;
for ( var i = 0; i < myArray.length; i = i + 1 ) {
if(i % 2 == 1){
tocArr[j] = myArray[ i ];
j++;
}else{
callcostArr[k] = myArray[ i ];
k++;
}
}
var toc = tocArr.toString();
var callcost = callcostArr.toString();
alert( toc );
alert( callcost );
I am trying to replace values in a string with the comparable jSON property in an object.
var value = "/sessions/:sessionId/events/:id";
var result = replace(value, { sessionId : 1 , id : 23 });
// result : "/sessions/1/events/23"
console.log(result);
Is it possible with JavaScript (I'm sure it is)? Not sure about the most efficient way to do this and how to handle it when all the values inside the template string are not matched.
Thanks in advance.
Update (Solution)
var url = function (template, parameters) {
var extra = [];
for (param in parameters) {
if (value.indexOf(param) < 0) {
extra.push(param + '=' + parameters[param]);
}
}
var result = template.replace(/:(\w+)/g, function (substring, match) {
var routeValue = parameters[match];
if (!routeValue) {
throw "missing route value for " + match + ' in "' + template +'"';
}
return routeValue;
});
if (result.indexOf("/:") > 0) {
throw "not all route values were matched";
}
return (extra.length === 0) ? result : result + "?" + extra.join("&");
};
var value = "/sessions/:sessionId/events/:id";
var data = {
sessionId: 1,
id: 23,
term: "butter"
};
// result : /sessions/1/events/21?term=butter
console.log(url(value, data));
A regex would work just fine here.
var value = "/sessions/:sessionId/events/:id";
var obj = { sessionId : 1 , id : 23 };
var result = value.replace(/:(\w+)(\/|\b)/g, function(substring, match, nextMatch){
return obj[match] + nextMatch;
});
Assuming you have the following javascript object:
var myObject = { sessionId : 1 , id : 23 };
you can loop each property and do a replace on the original string...
var value = "/sessions/:sessionId/events/:id";
for(var item in myObject){
value = value.replace(item, myObject[item]);
}
//value = "/sessions/:1/events/:23"
Here is a working example
It is not clear if you want to keep the : characters or not. If not, then you can just include that in your replace function:
value = value.replace(':' + item, myObject[item]);
Checking for missing parameters
If you have any extra values in your object that do not exist in your input string, then they will not have any effect. If however, you want to take action if one of the items is not found in the original string, then you can do a check in the loop:
var noMatch = false;
for(var item in myObject){
if(value.indexOf(item) < 0){
noMatch = true;
}
value = value.replace(item, myObject[item]);
}
if(noMatch){
//something is wrong!
}
Dealing with JSON
If you do actually have a JSON string to begin with, you can convert that to an object with the following:
var jsonString = '{"sessionId": 1, "id": 23}';
var myObject = JSON.parse(jsonString);
here is another way of doing it.
http://jsfiddle.net/rayweb_on/suHej/
var value = "/sessions/:sessionId/events/:id";
var source = { sessionId : 1 , id : 23 };
var result = value.replace(":sessionId",source.sessionId);
var result = result.replace(":id",source.id);
console.log(result);
I have a string that looks something like the following 'test:1;hello:five;just:23'. With this string I need to be able to do the following.
....
var test = MergeTokens('test:1;hello:five;just:23', 'yes:23;test:567');
...
The end result should be 'test:567;hello:five;just:23;yes:23' (note the exact order of the tokens is not that important).
Just wondering if anyone has any smart ideas of how to go about this. I was thinking a regex replace on each of the tokens on right and if a replace didn't occur because there was not match just append it. But maybe there is better way.
Cheers
Anthony
Edit: The right side should override the left. The left being what was originally there and the right side being the new content. Another way of looking at it, is that you only keep the tokens on the left if they don't exist on the right and you keep all the tokens on the right.
#Ferdinand
Thanks for the reply. The problem is the efficiency with which the solution you proposed. I was initially thinking down similar lines but discounted it due to the O(n*z) complexity of the merge (where n and z is the number tokens on the left and right respectively) let alone the splitting and joining.
Hence why I was trying to look down the path of a regex. Maybe behind the scenes, regex is just as bad or worse, but having a regex which removes any token from the left string that exists on the right (O(n) for the total amount of token on the right) and then just add the 2 string together (i.e. vat test = test1 + test2) seems more efficient. thanks
I would use join() and split() to create some utility functions to pack and unpack your token data to an object:
// Unpacks a token string into an object.
function splitTokens(str) {
var data = {}, pairs = str.split(';');
for (var i = 0; i < pairs.length; ++i) {
var pair = pairs[i].split(':');
data[pair[0]] = pair[1];
}
return data;
}
// Packs an object into a token string.
function joinTokens(data) {
var pairs = [];
for (var key in data) {
pairs.push(key + ":" + data[key]);
}
return pairs.join(';');
}
Using these, merging is easy:
// Merges all token strings (supports a variable number of arguments).
function mergeTokens() {
var data = {};
for (var i = 0; i < arguments.length; ++i) {
var d = splitTokens(arguments[i]);
for (var key in d) {
data[key] = d[key];
}
}
return joinTokens(data);
}
The utility functions are also useful if you want to extract some keys (say,"test") and/or check for existence:
var data = splitTokens(str);
if (data["test"] === undefined) {
// Does not exist
} else {
alert("Value of 'test': " + data["test"]);
}
The following is what I ended thiking about. What do you guys recon?
Thanks
Anthony
function Tokenizer(input, tokenSpacer, tokenValueSpacer) {
this.Tokenizer = {};
this.TokenSpacer = tokenSpacer;
this.TokenValueSpacer = tokenValueSpacer;
if (input) {
var TokenizerParts = input.split(this.TokenSpacer);
var i, nv;
for (i = 0; i < TokenizerParts.length; i++) {
nv = TokenizerParts[i].split(this.TokenValueSpacer);
this.Tokenizer[nv[0]] = nv[1];
}
}
}
Tokenizer.prototype.add = function(name, value) {
if (arguments.length == 1 && arguments[0].constructor == Object) {
this.addMany(arguments[0]);
return;
}
this.Tokenizer[name] = value;
}
Tokenizer.prototype.addMany = function(newValues) {
for (nv in newValues) {
this.Tokenizer[nv] = newValues[nv];
}
}
Tokenizer.prototype.remove = function(name) {
if (arguments.length == 1 && arguments[0].constructor == Array) {
this.removeMany(arguments[0]);
return;
}
delete this.Tokenizer[name];
}
Tokenizer.prototype.removeMany = function(deleteNames) {
var i;
for (i = 0; i < deleteNames.length; i++) {
delete this.Tokenizer[deleteNames[i]];
}
}
Tokenizer.prototype.MergeTokenizers = function(newTokenizer) {
this.addMany(newTokenizer.Tokenizer);
}
Tokenizer.prototype.getTokenString = function() {
var nv, q = [];
for (nv in this.Tokenizer) {
q[q.length] = nv + this.TokenValueSpacer + this.Tokenizer[nv];
}
return q.join(this.TokenSpacer);
}
Tokenizer.prototype.toString = Tokenizer.prototype.getTokenString;
i am a few years late, but i think this is what you are looking for:
function MergeTokens(input, replace){
var replaceTokens = replace.split(";");
for(i=0; i<replaceTokens.length; i++){
var pair = replaceTokens[i].split(":");
var result = input;
regString = "\\b" + pair[0] + ":[\\w]*\\b";
var reg = new RegExp(regString);
if(reg.test(result)){
result = result.replace(reg, replaceTokens[i]);
}
else{
result = result + replaceTokens[i];
}
}
return result;
}