I'm trying to write a function that will run encodeURIComponent on arrays or objects regardless of the depth. It all seems to go well until I return the final result.
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script>
function encodeURI_array($Array) {
$Result = [];
if($Array !== null && typeof $Array === 'object') {
//for(var key in $Array) {
Object.keys($Array).forEach(function (key) {
if($Array[key] !== null && typeof $Array[key] === 'object') {
console.log("encode array: " + key + " : " + $Array[key]);
$Result[key] = encodeURI_array($Array[key]);
} else {
$Result[key] = encodeURIComponent($Array[key],"UTF-8").replace(/\+/g, ' ').replace("%26","&").replace("%2C",",");
console.log("encode strings: " + key + " : " + $Result[key]);
}
});
console.log("Final result");
console.log($Result);
return $Result;
} else {
$Result = encodeURIComponent($Array,"UTF-8").replace(/\+/g, ' ').replace("%26","&").replace("%2C",",");
console.log("encode string: " + $Result);
return $Result;
}
}
$TestArray = [{"Key1":"Value1"},{"Key2":"Value2"},{"Key3":"Value3"}];
$TestArray2 = {"Key":"Value"};
(encodeURI_array($TestArray));
//console.log(encodeURI_array($TestArray2));
</script>
For this script, the very last result returns only the last object in the array when it should be returning an array of objects.
Related
How can i check which JSON value exist in JSON Array? Here are my solution:
var jsonArr = "[{"F_1":"c4024087","F_2":"9a565962","F_3":"23026","F_4":"John","F_5":"Doe"},{"F_1":"dbb88908","F_2":"bc6fd3bb","F_3":"19727","F_4":"Mike","F_5":"Long"}]"
Find the value:
var toFind = "9a565962";
var checkObj = jsonArr.find(o => o.F_2 == toFind );
if (typeof checkObj === "undefined") {
console.log("Value " + toFind + " not exists in Array. Do something!");
} else (Object.keys(checkObj).length > 0) {
console.log("Value " + toFind + " exists in Array. Do something else");
}
Is this the best way to find a value in a array?
$jsondata = file_get_contents("/json/API.php");
$array = json_decode($jsondata,true);
foreach($array as $k=>$val):
if($id =! $val){
echo '<b>id: '.$k.'</b></br>';
$keys = array_keys($val);
foreach($keys as $key):
echo ' '.ucfirst($key).' = '.$val[$key].'</br>';
endforeach;
endforeach;
}
Probably it will solve your problem Best Regards
I have a custom file which can serve for both server side a.gs as well as cleint side a.js, both has same functions defined
instead of having a.gs and a.js how will I make
function include(filename) {
return HtmlService.createHtmlOutputFromFile('<script>'+a.gs+'</script>').getContent();
}
something like above.
In your doGet function you can check if a specific parameter is present and then send all or part of the code contained in a.gs to the client.
function doGet(e) {
if(e.parameter.func) {
var out = ContentService.createTextOutput(this[e.parameter.func].toString());
out.setMimeType(ContentService.MimeType.JAVASCRIPT);
return out;
}
}
Now you can add this line to your html file
<script type="text/javascript" src="https://script.google.com/macros/s/<id>/exec?func=myFunction"></script>
in order to use myFunction on the client.
But if you want to make everything in a.gs available to the client and not just a single function you could do this
function genCode2(obj) {
if(obj instanceof Array) return JSON.stringify(obj);
if(obj === null) return "null";
if(typeof(obj) === "undefined") return "undefined";
if(typeof(obj) === "object") {
var str = "{\n";
for(key in obj) {
if(typeof obj[key] === "function") {
var s = obj[key].toString() + "\n";
if(s.indexOf("[native code") < 0) str += "\"" + key + "\": " + s + ",\n";
} else {
str += "\"" + key + "\": " + genCode2(obj[key]) + ",\n";
}
}
return str + "\n}";
}
return JSON.stringify(obj);
}
function genCode(obj) {
var str = "";
for(key in obj) {
if(typeof obj[key] === "function") {
var s = obj[key].toString() + "\n";
if(s.indexOf("[native code") < 0) str += s;
} else {
str += "var " + key + " = " + genCode2(obj[key]) + ";\n";
}
}
return str + "";
}
function doGet(e) {
if(e.parameter.file === "a.gs") {
var out = ContentService.createTextOutput(genCode(this));
out.setMimeType(ContentService.MimeType.JAVASCRIPT);
return out;
}
}
And then put <script type="text/javascript" src="https://script.google.com/macros/s/<id>/exec?file=a.gs"></script> in the html file.
But on the other hand, maybe you could just put a js file into your google drive which you could then load in a.gs and send to the client or evaluate with eval.
function objectToArray (object) {
var array = [];
var str = "";
for (var key in object) {
array.push(key);
array.push(object[key]);
if (object.hasOwnProperty(key)) {
str += key + " is " + object[key] + "";
}
}
console.log(array);
}
objectToArray({name: "Marcia", age: 101});
The output is [ 'name', 'Marcia', 'age', 101 ] and I need it to be ["name is Marcia", "age is 101"].
Instead of this:
array.push(key);
array.push(object[key]);
if (object.hasOwnProperty(key)) {
str += key + " is " + object[key] + "";
}
You want this:
if (object.hasOwnProperty(key)) {
array.push( key + " is " + object[key] + "" );
}
#VoteyDisciple has correctly pointed out where you went wrong with your approach. An alternate (shorter) way to implement your function is:
function objectToArray (object) {
return Object.keys(object).map(function (key) {
return key + " is " + object[key];
});
}
var arr = objectToArray({name: "Marcia", age: 101});
console.log(arr);
I need a function that can serialize object of type {"a":"val", "b":{}, "c":[{}]} without JSON.stringify (cause the environment simply does not has JSON object) or using jquery and any other library. The code bellow is what I have at this moment:
function objToString(obj) {
if (obj == null) return null;
var index = 0;
var str = '{';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str += index != 0 ? "," : "";
str += '"' + p + '":' + (typeof (obj[p]) == 'object' ? objToString(obj[p]) : itemToJsonItem(obj[p]));
index++;
}
}
str += "}";
return str;
}
function itemToJsonItem(item) {
return isNaN(item) ? '"' + item + '"' : item;
}
This function can deal with objects, nested objects but not with arrays. Node "c" from mentioned object will looks like "c":{"0":{...}} and not like array. Unsurprising "c".constructor === Array is false cause it interpreted as function and not as array. This is complete code where you can see what happens.
<div id="div_result"></div>
<script>
var test = { "a": "val", "b": [{"c":"val c"}]};
function objToString(obj) {
if (obj == null) return null;
var index = 0;
var str = '{';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str += index != 0 ? "," : "";
str += '"' + p + '":' + (typeof (obj[p]) == 'object' ? objToString(obj[p]) : itemToJsonItem(obj[p]));
index++;
}
}
str += "}";
return str;
}
function itemToJsonItem(item) {
return isNaN(item) ? '"' + item + '"' : item;
}
document.getElementById("div_result").innerHTML = objToString(test);
</script>
I will really appreciate help, at this moment serialized object created by toSerialize function inside of each object but we want to make it with outside standard function.
Try to use JSON 3. It is polyfill library for window.JSON. It exposes JSON.stringify and JSON.parse methods.
Trying to get my indents working right on a prettyprint JS function..
Just need a simple JSON stringify that pretty prints.
I'm in a locked down older JS server environment. There's no JSON obj. I can't use JSON.stringify or the JSON polyfills, so I have to write my own func..
function prettyprint(obj, ind){
ind = ind || 0;
var indent = spaces(ind), str = '';
if((typeof obj).match(/string|number/) || obj == null){
return indent + obj;
} else if(obj.push){
for(var i=0;i<obj.length;i++){
str = str + prettyprint(obj[i], ind+2 || 2);
}
return indent + '[' + str + ']\n';
} else {
str = indent + ' {';
for(var i in obj){
str = str + '\n' + indent+' '+ i + ': ' + prettyprint(obj[i], ind+2);
}
return str +'\n';
}
return str;
function spaces(n){
return Array(n).join(' ');
}
}
This is what I'm trying etc.. prettyprint({'a':'b','b':{'c':'d'}})
I thought this would be interesting to solve; and I tried modifying your code as a starting point, but quickly found that managing commas in the right places, and carriage returns was getting very complicated.
So I turned it into code that runs through the object passed to it, and emits tokens as it progresses to format an output string. I've pasted the code below.
prettyPrint.js:
prettyPrint = function (data) {
return new prettyPrint.processor(data).output;
}
prettyPrint.indentString = ' ';
prettyPrint.processor = function (data) {
var indent = 0,
output = '',
tokens = {
value: 1,
openArray: 2,
arrayValueSeparator: 3,
closeArray: 4,
openObject: 5,
objectValueName: 6,
objectValueSeparator: 7,
closeObject: 8
};
function isArray(unknown) {
return Object.prototype.toString.call(unknown) === '[object Array]';
}
function isObject(unknown) {
return Object.prototype.toString.call(unknown) === '[object Object]';
}
function space() {
var count = indent;
var result = '';
while (count--) result += prettyPrint.indentString;
return result;
}
function emit(tokenType, value) {
switch (tokenType) {
case tokens.value:
output += value;
break;
case tokens.openArray:
output += '[';
break;
case tokens.arrayValueSeparator:
output += ', ';
break;
case tokens.closeArray:
output += ']';
break;
case tokens.openObject:
output += '{';
indent += 1;
break;
case tokens.objectValueName:
output += '\n' + space() + (/^[a-z][a-z0-9_]*$/i.test(value) ? value : "'" + value + "'") + ': ';
break;
case tokens.objectValueSeparator:
output += ',';
break;
case tokens.closeObject:
indent -= 1;
output += '\n' + space() + '}';
break;
}
}
function process(data) {
var p, first;
if (data === undefined) {
return;
}
// Don't surround null with quotes.
if (data === null) {
emit(prettyPrint.tokens.value, 'null');
}
else if (isArray(data)) {
emit(tokens.openArray);
first = true;
for (p in data) {
if (!first) {
emit(tokens.arrayValueSeparator);
}
process(data[p]);
first = false;
}
emit(tokens.closeArray);
}
else if (isObject(data)) {
emit(tokens.openObject);
first = true;
for (p in data) {
if (data.hasOwnProperty(p) && data[p] !== undefined) {
if (!first) {
emit(tokens.objectValueSeparator);
}
emit(tokens.objectValueName, p);
process(data[p]);
first = false;
}
}
emit(tokens.closeObject);
}
else if (data instanceof Date) {
emit(tokens.value, "'" + data.toISOString() + "'");
}
else if (typeof data === 'number') {
emit(tokens.value, isNaN(data) ? 'null' : data.toString());
}
else {
emit(tokens.value, "'" + data.toString() + "'");
}
}
// Start processing the data.
process(data);
// Export the data.
this.output = output;
}
prettyPrint.html:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Pretty Print Testing</title>
<script type="text/javascript" src="prettyPrint.js"></script>
</head>
<body>
<pre id="pretty1"></pre>
<pre id="pretty2"></pre>
<script type="text/javascript">
document.getElementById('pretty1').innerHTML = prettyPrint({ 'a': 'b', 'b': { 'c': 'd' } });
document.getElementById('pretty2').innerHTML = prettyPrint([1, 2, "three", { 'complex-name': [1] }, { simpleName: { subArray: [1, 2, 3], subString: "Hello" } }]);
</script>
</body>
</html>
Output:
{
a: 'b',
b: {
c: 'd'
}
}
[1, 2, 'three', {
'complex-name': [1]
}, {
simpleName: {
subArray: [1, 2, 3],
subString: 'Hello'
}
}]
I hope this is useful to you.
This what I ended up with:
function pp(obj, ind){
ind = ind || 0;
if(typeof obj === 'object' && obj !== null){
var s = sp(ind) + (obj.push ? '[':'{') + '\n';
for(i in obj)
s += sp(ind+2) + i + ': ' + pp(obj[i], ind+2);
obj = s + sp(ind) + (obj.push ? ']':'}');
}
return obj + '\n';
function sp(n){
return Array(n).join(' ');
}
}