Remove value from a multivalue field? - xpages

I have a multivalue field on my document that I would like to remove a value based on the value.
I came up with this:
var doc:NotesDocument = rowData.getDocument();
var item:NotesItem = doc.getFirstItem("ValidProjects");
var a:Array = item.getValues()
for (var v in a)
dBar.info("Before removed V=" + v );
removeFromArray(a,compositeData.ProjectID);
doc.replaceItemValue("ValidProjects",a );
for (var v in a)
dBar.info("After removed V=" + v);
doc.save();
function removeFromArray(arr, val) {
for(var i=0; i<arr.length; i++) {
dBar.info("Value = " + arr[i] + " Remove = " + val);
if(arr[i] == val) {
dBar.info("Removing " + i)
arr.splice(i, 1);
break;
}
}
}
The removeFromArray is being called successfully and I can see the "Removing 0" message displayed in the debugbar as expected but the array does not change at all and the value is not removed. Any ideas?

Treat the ItemValues as Vector.
function removeFromItemValues(java.util.Vector vector, val) {
// see http://docs.oracle.com/javase/6/docs/api/java
vector.remove(val);
return vector; //Optional
}
Hope that helps

Just a quick shot... I am not sure that arguments are passed "by reference"...?
If not, then that is the reason. I would normally prefer to use a function to return a value instead. From a programming point of view I find it more clear to read what the code does. In this particular example you would change your code to something like:
function removeFromArray(arr, val) {
for(var i=0; i<arr.length; i++) {
dBar.info("Value = " + arr[i] + " Remove = " + val);
if(arr[i] == val) {
dBar.info("Removing " + i)
arr.splice(i, 1);
break;
}
}
return arr;
}
and then you would call it like:
a = removeFromArray(a,compositeData.ProjectID);
You do not write whether you can see a change in your "After..." message? - or you just can see in the document that the value did not change?
Best regards
/John

Related

How to construct a binary tree from a infix string with brackets?

A non-empty tree is defined as {L,a,R}, L is left subtree, and R is Right subtree. {} for subtree is empty.
for example, {{{{},3,{}},2,{{},1,{}}},4,{{{},5,{}},6,{}}} constructs an binary tree like the picture.tree constructed from the string
I have found a question for constructs an binary tree from a prefix expression with brackets, but I still have no idea for how to doing this.
I did not get a reply on which data structure or language you expect to use, but here is an implementation of a recursive parser in JavaScript.
It uses a regular expression to tokenise the input into braces and data.
From those tokens it creates instances of a typical Node class.
Finally it outputs that structured tree in a simple, rotated view:
class Node {
constructor(left, value, right) {
this.left = left;
this.value = value;
this.right = right;
}
toString() {
return (this.right ? this.right.toString().replace(/^/gm, " ") + "\n" : "")
+ this.value
+ (this.left ? "\n" + this.left.toString().replace(/^/gm, " ") : "");
}
}
function createTree(s) {
const tokens = s.matchAll(/,([^{},]+),|[{}]|(.)/g);
function getToken(expect) {
let [all, value, error] = tokens.next().value;
value ||= all;
if (error || expect && !expect.includes(all)) throw "Unexpected '" + all + "'";
return value;
}
function dfs(readOpening) {
if (readOpening) getToken("{");
if (getToken("{}") == "}") return null;
const node = new Node(dfs(), getToken(), dfs(true));
getToken("}");
return node;
}
return dfs(true);
}
// Demo
const s = "{{{{},3,{}},2,{{},1,{}}},4,{{{},5,{}},6,{}}}";
const root = createTree(s);
console.log(root.toString()); // rotated view, with root at the left
Thanks for answerign my question. I finally came up with an naive method by myself. I used recursive function to deal with token and create nodes. It used a counter to judge whether brackets is closed. Here is my code in C++.
createTree(string inp){
int leftBracket = 0,rightBracket = 0;
if (inp.length() <= 2) {
return nullptr;
}
else {
for (int i = 1;;i++) {
if (leftBracket == rightBracket && inp[i] >= '0' && inp[i] <= '9') {
treeNode* newNode = new treeNode(inp[i]-'0', createTree(inp.substr(1, i - 2)), createTree(inp.substr(i + 2, inp.length() - i - 3)));
nodeCounter++;
return newNode;
}
else {
if (inp[i] == '{') {
leftBracket++;
}
else if (inp[i] == '}') {
rightBracket++;
}
}
}
}
}

stored exponential value in mongodb [duplicate]

I'm looking for a good JavaScript equivalent of the C/PHP printf() or for C#/Java programmers, String.Format() (IFormatProvider for .NET).
My basic requirement is a thousand separator format for numbers for now, but something that handles lots of combinations (including dates) would be good.
I realize Microsoft's Ajax library provides a version of String.Format(), but we don't want the entire overhead of that framework.
Current JavaScript
From ES6 on you could use template strings:
let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!"
See Kim's answer below for details.
Older answer
Try sprintf() for JavaScript.
If you really want to do a simple format method on your own, don’t do the replacements successively but do them simultaneously.
Because most of the other proposals that are mentioned fail when a replace string of previous replacement does also contain a format sequence like this:
"{0}{1}".format("{1}", "{0}")
Normally you would expect the output to be {1}{0} but the actual output is {1}{1}. So do a simultaneous replacement instead like in fearphage’s suggestion.
Building on the previously suggested solutions:
// First, checks if it isn't implemented yet.
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
outputs
ASP is dead, but ASP.NET is alive! ASP {2}
If you prefer not to modify String's prototype:
if (!String.format) {
String.format = function(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
Gives you the much more familiar:
String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');
with the same result:
ASP is dead, but ASP.NET is alive! ASP {2}
It's funny because Stack Overflow actually has their own formatting function for the String prototype called formatUnicorn. Try it! Go into the console and type something like:
"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});
You get this output:
Hello, Gabriel, are you feeling OK?
You can use objects, arrays, and strings as arguments! I got its code and reworked it to produce a new version of String.prototype.format:
String.prototype.formatUnicorn = String.prototype.formatUnicorn ||
function () {
"use strict";
var str = this.toString();
if (arguments.length) {
var t = typeof arguments[0];
var key;
var args = ("string" === t || "number" === t) ?
Array.prototype.slice.call(arguments)
: arguments[0];
for (key in args) {
str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
}
}
return str;
};
Note the clever Array.prototype.slice.call(arguments) call -- that means if you throw in arguments that are strings or numbers, not a single JSON-style object, you get C#'s String.Format behavior almost exactly.
"a{0}bcd{1}ef".formatUnicorn("FOO", "BAR"); // yields "aFOObcdBARef"
That's because Array's slice will force whatever's in arguments into an Array, whether it was originally or not, and the key will be the index (0, 1, 2...) of each array element coerced into a string (eg, "0", so "\\{0\\}" for your first regexp pattern).
Neat.
Number Formatting in JavaScript
I got to this question page hoping to find how to format numbers in JavaScript, without introducing yet another library. Here's what I've found:
Rounding floating-point numbers
The equivalent of sprintf("%.2f", num) in JavaScript seems to be num.toFixed(2), which formats num to 2 decimal places, with rounding (but see #ars265's comment about Math.round below).
(12.345).toFixed(2); // returns "12.35" (rounding!)
(12.3).toFixed(2); // returns "12.30" (zero padding)
Exponential form
The equivalent of sprintf("%.2e", num) is num.toExponential(2).
(33333).toExponential(2); // "3.33e+4"
Hexadecimal and other bases
To print numbers in base B, try num.toString(B). JavaScript supports automatic conversion to and from bases 2 through 36 (in addition, some browsers have limited support for base64 encoding).
(3735928559).toString(16); // to base 16: "deadbeef"
parseInt("deadbeef", 16); // from base 16: 3735928559
Reference Pages
Quick tutorial on JS number formatting
Mozilla reference page for toFixed() (with links to toPrecision(), toExponential(), toLocaleString(), ...)
From ES6 on you could use template strings:
let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!"
Be aware that template strings are surrounded by backticks ` instead of (single) quotes.
For further information:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Note:
Check the mozilla-site to find a list of supported browsers.
jsxt, Zippo
This option fits better.
String.prototype.format = function() {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
var regexp = new RegExp('\\{'+i+'\\}', 'gi');
formatted = formatted.replace(regexp, arguments[i]);
}
return formatted;
};
With this option I can replace strings like these:
'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');
With your code the second {0} wouldn't be replaced. ;)
I use this simple function:
String.prototype.format = function() {
var formatted = this;
for( var arg in arguments ) {
formatted = formatted.replace("{" + arg + "}", arguments[arg]);
}
return formatted;
};
That's very similar to string.format:
"{0} is dead, but {1} is alive!".format("ASP", "ASP.NET")
For Node.js users there is util.format which has printf-like functionality:
util.format("%s world", "Hello")
I'm surprised no one used reduce, this is a native concise and powerful JavaScript function.
ES6 (EcmaScript2015)
String.prototype.format = function() {
return [...arguments].reduce((p,c) => p.replace(/%s/,c), this);
};
console.log('Is that a %s or a %s?... No, it\'s %s!'.format('plane', 'bird', 'SOman'));
< ES6
function interpolate(theString, argumentArray) {
var regex = /%s/;
var _r=function(p,c){return p.replace(regex,c);}
return argumentArray.reduce(_r, theString);
}
interpolate("%s, %s and %s", ["Me", "myself", "I"]); // "Me, myself and I"
How it works:
reduce applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
var _r= function(p,c){return p.replace(/%s/,c)};
console.log(
["a", "b", "c"].reduce(_r, "[%s], [%s] and [%s]") + '\n',
[1, 2, 3].reduce(_r, "%s+%s=%s") + '\n',
["cool", 1337, "stuff"].reduce(_r, "%s %s %s")
);
Here's a minimal implementation of sprintf in JavaScript: it only does "%s" and "%d", but I have left space for it to be extended. It is useless to the OP, but other people who stumble across this thread coming from Google might benefit from it.
function sprintf() {
var args = arguments,
string = args[0],
i = 1;
return string.replace(/%((%)|s|d)/g, function (m) {
// m is the matched format, e.g. %s, %d
var val = null;
if (m[2]) {
val = m[2];
} else {
val = args[i];
// A switch statement so that the formatter can be extended. Default is %s
switch (m) {
case '%d':
val = parseFloat(val);
if (isNaN(val)) {
val = 0;
}
break;
}
i++;
}
return val;
});
}
Example:
alert(sprintf('Latitude: %s, Longitude: %s, Count: %d', 41.847, -87.661, 'two'));
// Expected output: Latitude: 41.847, Longitude: -87.661, Count: 0
In contrast with similar solutions in previous replies, this one does all substitutions in one go, so it will not replace parts of previously replaced values.
3 different ways to format javascript string
There are 3 different ways to format a string by replacing placeholders with the variable value.
Using template literal (backticks ``)
let name = 'John';
let age = 30;
// using backticks
console.log(`${name} is ${age} years old.`);
// John is 30 years old.
Using concatenation
let name = 'John';
let age = 30;
// using concatenation
console.log(name + ' is ' + age + ' years old.');
// John is 30 years old.
Creating own format function
String.prototype.format = function () {
var args = arguments;
return this.replace(/{([0-9]+)}/g, function (match, index) {
// check if the argument is there
return typeof args[index] == 'undefined' ? match : args[index];
});
};
console.log('{0} is {1} years old.'.format('John', 30));
JavaScript programmers can use String.prototype.sprintf at https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js. Below is example:
var d = new Date();
var dateStr = '%02d:%02d:%02d'.sprintf(
d.getHours(),
d.getMinutes(),
d.getSeconds());
I want to share my solution for the 'problem'. I haven't re-invented the wheel but tries to find a solution based on what JavaScript already does. The advantage is, that you get all implicit conversions for free. Setting the prototype property $ of String gives a very nice and compact syntax (see examples below). It is maybe not the most efficient way, but in most cases dealing with output it does not have to be super optimized.
String.form = function(str, arr) {
var i = -1;
function callback(exp, p0, p1, p2, p3, p4) {
if (exp=='%%') return '%';
if (arr[++i]===undefined) return undefined;
exp = p2 ? parseInt(p2.substr(1)) : undefined;
var base = p3 ? parseInt(p3.substr(1)) : undefined;
var val;
switch (p4) {
case 's': val = arr[i]; break;
case 'c': val = arr[i][0]; break;
case 'f': val = parseFloat(arr[i]).toFixed(exp); break;
case 'p': val = parseFloat(arr[i]).toPrecision(exp); break;
case 'e': val = parseFloat(arr[i]).toExponential(exp); break;
case 'x': val = parseInt(arr[i]).toString(base?base:16); break;
case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;
}
val = typeof(val)=='object' ? JSON.stringify(val) : val.toString(base);
var sz = parseInt(p1); /* padding size */
var ch = p1 && p1[0]=='0' ? '0' : ' '; /* isnull? */
while (val.length<sz) val = p0 !== undefined ? val+ch : ch+val; /* isminus? */
return val;
}
var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;
return str.replace(regex, callback);
}
String.prototype.$ = function() {
return String.form(this, Array.prototype.slice.call(arguments));
}
Here are a few examples:
String.format("%s %s", [ "This is a string", 11 ])
console.log("%s %s".$("This is a string", 11))
var arr = [ "12.3", 13.6 ]; console.log("Array: %s".$(arr));
var obj = { test:"test", id:12 }; console.log("Object: %s".$(obj));
console.log("%c", "Test");
console.log("%5d".$(12)); // ' 12'
console.log("%05d".$(12)); // '00012'
console.log("%-5d".$(12)); // '12 '
console.log("%5.2d".$(123)); // ' 120'
console.log("%5.2f".$(1.1)); // ' 1.10'
console.log("%10.2e".$(1.1)); // ' 1.10e+0'
console.log("%5.3p".$(1.12345)); // ' 1.12'
console.log("%5x".$(45054)); // ' affe'
console.log("%20#2x".$("45054")); // ' 1010111111111110'
console.log("%6#2d".$("111")); // ' 7'
console.log("%6#16d".$("affe")); // ' 45054'
Adding to zippoxer's answer, I use this function:
String.prototype.format = function () {
var a = this, b;
for (b in arguments) {
a = a.replace(/%[a-z]/, arguments[b]);
}
return a; // Make chainable
};
var s = 'Hello %s The magic number is %d.';
s.format('world!', 12); // Hello World! The magic number is 12.
I also have a non-prototype version which I use more often for its Java-like syntax:
function format() {
var a, b, c;
a = arguments[0];
b = [];
for(c = 1; c < arguments.length; c++){
b.push(arguments[c]);
}
for (c in b) {
a = a.replace(/%[a-z]/, b[c]);
}
return a;
}
format('%d ducks, 55 %s', 12, 'cats'); // 12 ducks, 55 cats
ES 2015 update
All the cool new stuff in ES 2015 makes this a lot easier:
function format(fmt, ...args){
return fmt
.split("%%")
.reduce((aggregate, chunk, i) =>
aggregate + chunk + (args[i] || ""), "");
}
format("Hello %%! I ate %% apples today.", "World", 44);
// "Hello World, I ate 44 apples today."
I figured that since this, like the older ones, doesn't actually parse the letters, it might as well just use a single token %%. This has the benefit of being obvious and not making it difficult to use a single %. However, if you need %% for some reason, you would need to replace it with itself:
format("I love percentage signs! %%", "%%");
// "I love percentage signs! %%"
+1 Zippo with the exception that the function body needs to be as below or otherwise it appends the current string on every iteration:
String.prototype.format = function() {
var formatted = this;
for (var arg in arguments) {
formatted = formatted.replace("{" + arg + "}", arguments[arg]);
}
return formatted;
};
I use a small library called String.format for JavaScript which supports most of the format string capabilities (including format of numbers and dates), and uses the .NET syntax. The script itself is smaller than 4 kB, so it doesn't create much of overhead.
I'll add my own discoveries which I've found since I asked:
number_format (for thousand separator/currency formatting)
sprintf (same author as above)
Sadly it seems sprintf doesn't handle thousand separator formatting like .NET's string format.
If you are looking to handle the thousands separator, you should really use toLocaleString() from the JavaScript Number class since it will format the string for the user's region.
The JavaScript Date class can format localized dates and times.
Very elegant:
String.prototype.format = function (){
var args = arguments;
return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (curlyBrack, index) {
return ((curlyBrack == "{{") ? "{" : ((curlyBrack == "}}") ? "}" : args[index]));
});
};
// Usage:
"{0}{1}".format("{1}", "{0}")
Credit goes to (broken link) https://gist.github.com/0i0/1519811
There is "sprintf" for JavaScript which you can find at http://www.webtoolkit.info/javascript-sprintf.html.
The PHPJS project has written JavaScript implementations for many of PHP's functions. Since PHP's sprintf() function is basically the same as C's printf(), their JavaScript implementation of it should satisfy your needs.
I use this one:
String.prototype.format = function() {
var newStr = this, i = 0;
while (/%s/.test(newStr))
newStr = newStr.replace("%s", arguments[i++])
return newStr;
}
Then I call it:
"<h1>%s</h1><p>%s</p>".format("Header", "Just a test!");
I have a solution very close to Peter's, but it deals with number and object case.
if (!String.prototype.format) {
String.prototype.format = function() {
var args;
args = arguments;
if (args.length === 1 && args[0] !== null && typeof args[0] === 'object') {
args = args[0];
}
return this.replace(/{([^}]*)}/g, function(match, key) {
return (typeof args[key] !== "undefined" ? args[key] : match);
});
};
}
Maybe it could be even better to deal with the all deeps cases, but for my needs this is just fine.
"This is an example from {name}".format({name:"Blaine"});
"This is an example from {0}".format("Blaine");
PS: This function is very cool if you are using translations in templates frameworks like AngularJS:
<h1> {{('hello-message'|translate).format(user)}} <h1>
<h1> {{('hello-by-name'|translate).format( user ? user.name : 'You' )}} <h1>
Where the en.json is something like
{
"hello-message": "Hello {name}, welcome.",
"hello-by-name": "Hello {0}, welcome."
}
One very slightly different version, the one I prefer (this one uses {xxx} tokens rather than {0} numbered arguments, this is much more self-documenting and suits localization much better):
String.prototype.format = function(tokens) {
var formatted = this;
for (var token in tokens)
if (tokens.hasOwnProperty(token))
formatted = formatted.replace(RegExp("{" + token + "}", "g"), tokens[token]);
return formatted;
};
A variation would be:
var formatted = l(this);
that calls an l() localization function first.
For basic formatting:
var template = jQuery.validator.format("{0} is not a valid value");
var result = template("abc");
We can use a simple lightweight String.Format string operation library for Typescript.
String.Format():
var id = image.GetId()
String.Format("image_{0}.jpg", id)
output: "image_2db5da20-1c5d-4f1a-8fd4-b41e34c8c5b5.jpg";
String Format for specifiers:
var value = String.Format("{0:L}", "APPLE"); //output "apple"
value = String.Format("{0:U}", "apple"); // output "APPLE"
value = String.Format("{0:d}", "2017-01-23 00:00"); //output "23.01.2017"
value = String.Format("{0:s}", "21.03.2017 22:15:01") //output "2017-03-21T22:15:01"
value = String.Format("{0:n}", 1000000);
//output "1.000.000"
value = String.Format("{0:00}", 1);
//output "01"
String Format for Objects including specifiers:
var fruit = new Fruit();
fruit.type = "apple";
fruit.color = "RED";
fruit.shippingDate = new Date(2018, 1, 1);
fruit.amount = 10000;
String.Format("the {type:U} is {color:L} shipped on {shippingDate:s} with an amount of {amount:n}", fruit);
// output: the APPLE is red shipped on 2018-01-01 with an amount of 10.000
Just in case someone needs a function to prevent polluting global scope, here is the function that does the same:
function _format (str, arr) {
return str.replace(/{(\d+)}/g, function (match, number) {
return typeof arr[number] != 'undefined' ? arr[number] : match;
});
};
For those who like Node.JS and its util.format feature, I've just extracted it out into its vanilla JavaScript form (with only functions that util.format uses):
exports = {};
function isString(arg) {
return typeof arg === 'string';
}
function isNull(arg) {
return arg === null;
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isBoolean(arg) {
return typeof arg === 'boolean';
}
function isUndefined(arg) {
return arg === void 0;
}
function stylizeNoColor(str, styleType) {
return str;
}
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (style) {
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
'\u001b[' + inspect.colors[style][3] + 'm';
} else {
return str;
}
}
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isSymbol(arg) {
return typeof arg === 'symbol';
}
function formatPrimitive(ctx, value) {
if (isUndefined(value))
return ctx.stylize('undefined', 'undefined');
if (isString(value)) {
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');
}
if (isNumber(value)) {
// Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
// so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
if (value === 0 && 1 / value < 0)
return ctx.stylize('-0', 'number');
return ctx.stylize('' + value, 'number');
}
if (isBoolean(value))
return ctx.stylize('' + value, 'boolean');
// For some reason typeof null is "object", so special case here.
if (isNull(value))
return ctx.stylize('null', 'null');
// es6 symbol primitive
if (isSymbol(value))
return ctx.stylize(value.toString(), 'symbol');
}
function arrayToHash(array) {
var hash = {};
array.forEach(function (val, idx) {
hash[val] = true;
});
return hash;
}
function objectToString(o) {
return Object.prototype.toString.call(o);
}
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
function isError(e) {
return isObject(e) &&
(objectToString(e) === '[object Error]' || e instanceof Error);
}
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
function formatError(value) {
return '[' + Error.prototype.toString.call(value) + ']';
}
function formatPrimitiveNoColor(ctx, value) {
var stylize = ctx.stylize;
ctx.stylize = stylizeNoColor;
var str = formatPrimitive(ctx, value);
ctx.stylize = stylize;
return str;
}
function isArray(ar) {
return Array.isArray(ar);
}
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
var name, str, desc;
desc = Object.getOwnPropertyDescriptor(value, key) || {value: value[key]};
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwnProperty(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (isNull(recurseTimes)) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function (line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function (line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (isUndefined(name)) {
if (array && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'")
.replace(/\\\\/g, '\\');
name = ctx.stylize(name, 'string');
}
}
return name + ': ' + str;
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwnProperty(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
String(i), true));
} else {
output.push('');
}
}
keys.forEach(function (key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
key, true));
}
});
return output;
}
function reduceToSingleString(output, base, braces) {
var length = output.reduce(function (prev, cur) {
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
}, 0);
if (length > 60) {
return braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
}
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
function formatValue(ctx, value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (ctx.customInspect &&
value &&
isFunction(value.inspect) &&
// Filter out the util module, it's inspect function is special
value.inspect !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
var ret = value.inspect(recurseTimes, ctx);
if (!isString(ret)) {
ret = formatValue(ctx, ret, recurseTimes);
}
return ret;
}
// Primitive types cannot have properties
var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}
// Look up the keys of the object.
var keys = Object.keys(value);
var visibleKeys = arrayToHash(keys);
if (ctx.showHidden) {
keys = Object.getOwnPropertyNames(value);
}
// This could be a boxed primitive (new String(), etc.), check valueOf()
// NOTE: Avoid calling `valueOf` on `Date` instance because it will return
// a number which, when object has some additional user-stored `keys`,
// will be printed out.
var formatted;
var raw = value;
try {
// the .valueOf() call can fail for a multitude of reasons
if (!isDate(value))
raw = value.valueOf();
} catch (e) {
// ignore...
}
if (isString(raw)) {
// for boxed Strings, we have to remove the 0-n indexed entries,
// since they just noisey up the output and are redundant
keys = keys.filter(function (key) {
return !(key >= 0 && key < raw.length);
});
}
// Some type of object without properties can be shortcutted.
if (keys.length === 0) {
if (isFunction(value)) {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(value);
}
// now check the `raw` value to handle boxed primitives
if (isString(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
return ctx.stylize('[String: ' + formatted + ']', 'string');
}
if (isNumber(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
return ctx.stylize('[Number: ' + formatted + ']', 'number');
}
if (isBoolean(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
return ctx.stylize('[Boolean: ' + formatted + ']', 'boolean');
}
}
var base = '', array = false, braces = ['{', '}'];
// Make Array say that they are Array
if (isArray(value)) {
array = true;
braces = ['[', ']'];
}
// Make functions say that they are functions
if (isFunction(value)) {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}
// Make RegExps say that they are RegExps
if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}
// Make dates with properties first say the date
if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}
// Make error with message first say the error
if (isError(value)) {
base = ' ' + formatError(value);
}
// Make boxed primitive Strings look like such
if (isString(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
base = ' ' + '[String: ' + formatted + ']';
}
// Make boxed primitive Numbers look like such
if (isNumber(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
base = ' ' + '[Number: ' + formatted + ']';
}
// Make boxed primitive Booleans look like such
if (isBoolean(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
base = ' ' + '[Boolean: ' + formatted + ']';
}
if (keys.length === 0 && (!array || value.length === 0)) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}
ctx.seen.push(value);
var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function (key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}
ctx.seen.pop();
return reduceToSingleString(output, base, braces);
}
function inspect(obj, opts) {
// default options
var ctx = {
seen: [],
stylize: stylizeNoColor
};
// legacy...
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (isBoolean(opts)) {
// legacy...
ctx.showHidden = opts;
} else if (opts) {
// got an "options" object
exports._extend(ctx, opts);
}
// set default options
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
if (isUndefined(ctx.depth)) ctx.depth = 2;
if (isUndefined(ctx.colors)) ctx.colors = false;
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
if (ctx.colors) ctx.stylize = stylizeWithColor;
return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
'bold': [1, 22],
'italic': [3, 23],
'underline': [4, 24],
'inverse': [7, 27],
'white': [37, 39],
'grey': [90, 39],
'black': [30, 39],
'blue': [34, 39],
'cyan': [36, 39],
'green': [32, 39],
'magenta': [35, 39],
'red': [31, 39],
'yellow': [33, 39]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'symbol': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red'
};
var formatRegExp = /%[sdj%]/g;
exports.format = function (f) {
if (!isString(f)) {
var objects = [];
for (var j = 0; j < arguments.length; j++) {
objects.push(inspect(arguments[j]));
}
return objects.join(' ');
}
var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function (x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s':
return String(args[i++]);
case '%d':
return Number(args[i++]);
case '%j':
try {
return JSON.stringify(args[i++]);
} catch (_) {
return '[Circular]';
}
default:
return x;
}
});
for (var x = args[i]; i < len; x = args[++i]) {
if (isNull(x) || !isObject(x)) {
str += ' ' + x;
} else {
str += ' ' + inspect(x);
}
}
return str;
};
Harvested from: https://github.com/joyent/node/blob/master/lib/util.js
I have a slightly longer formatter for JavaScript here...
You can do formatting several ways:
String.format(input, args0, arg1, ...)
String.format(input, obj)
"literal".format(arg0, arg1, ...)
"literal".format(obj)
Also, if you have say a ObjectBase.prototype.format (such as with DateJS) it will use that.
Examples...
var input = "numbered args ({0}-{1}-{2}-{3})";
console.log(String.format(input, "first", 2, new Date()));
//Outputs "numbered args (first-2-Thu May 31 2012...Time)-{3})"
console.log(input.format("first", 2, new Date()));
//Outputs "numbered args(first-2-Thu May 31 2012...Time)-{3})"
console.log(input.format(
"object properties ({first}-{second}-{third:yyyy-MM-dd}-{fourth})"
,{
'first':'first'
,'second':2
,'third':new Date() //assumes Date.prototype.format method
}
));
//Outputs "object properties (first-2-2012-05-31-{3})"
I've also aliased with .asFormat and have some detection in place in case there's already a string.format (such as with MS Ajax Toolkit (I hate that library).
Using Lodash you can get template functionality:
Use the ES template literal delimiter as an "interpolate" delimiter.
Disable support by replacing the "interpolate" delimiter.
var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!

Moving round content dynamically

I have an xpage, where fields are created dynamically. By default, there are 3, but you can click a button to add as many as you like, naming convention "ObjectiveDetails1", "ObjectiveDetails2" and so on.
I am trying to handle blank fields... For example, there is content in fields 1 and 2, nothing in 3 and 4, but content in 5. What I want to do, is shift content from field 5 into the first available blank, in this case 3. Likewise, if there is content in fields 1, 2, 4, 5, I then need content in 4, to go into field 3, and content in 5 to go into field 4 etc. At the moment, I'm managing to shift content up 1 only.
So if fields 2, 3, 4 are blank but 5 has content, it only moves the content into 4, where-as I need it to move into field 2.
I hope I've explained this well enough..... Current code is a little messy....
for (var i = 1; i < viewScope.rows+1; i++) {
print("Starting Array.....");
if(applicationScope.get("BreakAllCode")==true){
break;
}
var objFieldName:string = "ObjectiveDetails" +i;
print ("Field Name: " + objFieldName);
var fieldValue = document1.getItemValueString(objFieldName);
print ("Field Value: " + fieldValue);
if (fieldValue =="" || fieldValue==null){
print("EMPTY");
// We now need to delete the 3 fields related to this objective
var updFieldName:string = "ObjectiveUpdates" +i;
var SAFieldName:string = "ObjectiveSelfAssessment" +i;
// Before we delete the fields, we need to check if the next field is blank
// and if not, copy its contents into this field.
for (var n =i+1; n < viewScope.rows+1; n++) {
if(applicationScope.get("BreakAllCode")==true){
break;
}
if(document1.hasItem("ObjectiveDetails" +n)){
print("Next field: " +"ObjectiveDetails" +n);
var nextFieldValue = document1.getItemValueString("ObjectiveDetails" +n);
if (!nextFieldValue =="" || !nextFieldValue==null){
// Now copy the content into the field
var nextFieldName:string = "ObjectiveDetails" +n;
var previousNo = n-1;
var previousFieldName:string = "ObjectiveDetails" +previousNo;
print ("Previous field: " + previousFieldName);
document1.replaceItemValue(previousFieldName,nextFieldValue);
// Now clear the content from next field
document1.replaceItemValue(nextFieldName,"");
}else{
// Do nothing
}
}else{
print("Last field");
}
}
// Remove items from the document
//document1.removeItem(objFieldName);
//document1.removeItem(updFieldName);
//document1.removeItem(SAFieldName);
// Remove fields from our arrays
//viewScope.fields.splice(i-1, 1);
//viewScope.fields2.splice(i-1, 1);
//viewScope.fields3.splice(i-1, 1);
// Update the row variable
//viewScope.rows--;
//document1.replaceItemValue("rows",viewScope.rows);
//document1.save();
// We now need to "re-index" the array so that the fields are numbered corectly
}else{
print("We have a value");
}
}
Update with beforePageLoad:
viewScope.rows = document1.getItemValueInteger("rows");
var rowCount:integer = viewScope.rows;
var newCount:integer = 0;
while(newCount<rowCount){
if (!viewScope.fields) {
viewScope.fields = [];
viewScope.fields2 = [];
viewScope.fields3 = [];
}
viewScope.fields.push("ObjectiveDetails" + (viewScope.fields.length + 1));
viewScope.fields2.push("ObjectiveUpdates" + (viewScope.fields2.length + 1));
viewScope.fields3.push("ObjectiveSelfAssessment" + (viewScope.fields3.length + 1));
newCount++;
}
This should be your core algorithm:
var writeIndex = 0;
for (var readIndex = 1; readIndex <= viewScope.rows; readIndex++) {
var value = document1.getItemValueString("ObjectiveDetails" + readIndex);
if (value) {
writeIndex++;
if (readIndex !== writeIndex) {
document1.removeItem("ObjectiveDetails" + readIndex);
document1.replaceItemValue("ObjectiveDetails" + writeIndex, value);
}
} else {
document1.removeItem("ObjectiveDetails" + readIndex);
}
}
viewScope.rows = writeIndex;
The code
deletes all empty fields,
renames fields to ObjectiveDetails1, ObjectiveDetails2, ObjectiveDetails3,... and
writes the resulting number of rows back to viewScope variable "rows".
If I understood your problem correctly, then this code should work (not tested):
// define variables
var i,j,nRows,values,value,allowContinue,fieldname;
// collect values from document fields
nRows=viewScope.rows;
values=[];
for (i=0;i<nRows;i++) {
values.push(document1.getItemValueString("ObjectiveDetails"+(i+1).toFixed(0)));
}
// fill empty values
for (i=0;i<nRows-1;i++) {
if (values[i]) continue;
allowContinue=false;
for (j=i+1;j<nRows;j++) {
if (value=values[j]) {
values[i]=value;
values[j]="";
allowContinue=true;
break;
}
}
if (!allowContinue) break;
}
// write back to document and remove empty fields on the end
for (i=0;i<nRows;i++) {
fieldname="ObjectiveDetails"+(i+1).toFixed(0);
if (value=values[i]) document1.replaceItemValue(fieldname,value);
else document1.removeItem(fieldname);
}

AS3 (string).split quotation mark only

I want to split up a document by quotation it's marks. I see (here) that they're able to fake this answer by adding a '\' at the beginning of the quotation mark, however in my document there are hundreds of these strings I'm trying to cut string out of, so changing that manually would be a real pain and time taker.
Here's an example of the string I'm trying to cut from:
D
And here's an example of my current code:
private function onShopTextLoaded(e:Event):void
{
shopArrayOfWebsites = e.target.data.split(/\n/);
for (var i:String in shopArrayOfWebsites)
{
trace("shopArrayOriginal: " + shopArrayOfWebsites[i]);
var arrayString:String = shopArrayOfWebsites[i].split('"' /* << that won't work */ );
trace(arrayString[1]);
//shopArrayOfWebsites[i] = arrayString[1];
}
}
private function postInShopView():void
{
var iLevel:Number = 1;
var iSection:Number = 1;
var iShop:Number = 0;
for (var i:String in shopArrayOfWebsites)
{
iShop++;
if(iShop >= 5)
{
iSection++;
iShop = 0;
}
if(iSection >= 5)
{
iLevel++;
iSection = 1;
}
var shopStringEquiv:String = "L" + iLevel.toString() + "S" + iSection.toString() + "Shop" + iShop.toString();
if(global.shopTarget == shopStringEquiv)
{
var result:uint = ExternalInterface.call("showShopFrame", shopArrayOfWebsites[i]);
}
//trace(shopStringEquiv);
//trace(shopArrayOfWebsites[i]);
}
}
I get an error of:
ReferenceError: Error #1069: Property 1 not found on String and there is no default value.
So from here I'm not quite sure how I'm able to split up this document. Any ideas? Thanks!

How to remove duplicates from a string except it's first occurence

I've been given the following exercise but can't seem to get it working.
//Remove duplicate characters in a
// given string keeping only the first occurrences.
// For example, if the input is ‘tree traversal’
// the output will be "tre avsl".
// ---------------------
var params = 'tree traversal word';
var removeDuplicates = function (string) {
return string;
};
// This function runs the application
// ---------------------
var run = function() {
// We execute the function returned here,
// passing params as arguments
return removeDuplicates;
};
What I've done -
var removeDuplicates = function (string) {
var word ='';
for(var i=0; i < string.length; i++){
if(string[i] == " "){
word += string[i] + " ";
}
else if(string.lastIndexOf(string[i]) == string.indexOf(string[i]))
{
word += string[i];
}
}
return word;
};
I'm not allowed to use replaceAll and when I create an inner for loop it doesn't work.
<script>
function removeDuplicates(string)
{
var result = [];
var i = null;
var length = string.length;
for (i = 0; i < length; i += 1)
{
var current = string.charAt(i);
if (result.indexOf(current) === -1)
{
result.push(current);
}
}
return result.join("");
}
function removeDuplicatesRegex(string)
{
return string.replace(/(.)(?=\1)/g, "");
}
var str = "tree traversal";
alert(removeDuplicates(str));
</script>
First of all, the run function should be returning removeDuplicates(params), right?
You're on the right lines, but need to think about this condition again:
else if(string.lastIndexOf(string[i]) == string.indexOf(string[i]))
With i = 0 and taking 'tree traversal word' as the example, lastIndexOf() is going to be returning 5 (the index of the 2nd 't'), whereas indexOf() will be returning 0.
Obviously this isn't what you want, because 't' hasn't yet been appended to word yet (but it is a repeated character, which is what your condition does actually test for).
Because you're gradually building up word, think about testing to see if the character string[i] exists in word already for each iteration of your for loop. If it doesn't, append it.
(maybe this will come in handy: http://www.w3schools.com/jsref/jsref_search.asp)
Good luck!

Resources