Does JavaScript support array/list comprehensions like Python? - javascript

I'm practicing/studying both JavaScript and Python. I'm wondering if Javascript has the equivalence to this type of coding.
I'm basically trying to get an array from each individual integer from the string for practice purposes. I'm more proficient in Python than JavaScript
Python:
string = '1234-5'
forbidden = '-'
print([int(i) for i in str(string) if i not in forbidden])
Does Javascript have something similar for me to do above?

Update: Array comprehensions were removed from the standard. Quoting MDN:
The array comprehensions syntax is non-standard and removed starting with Firefox 58. For future-facing usages, consider using Array.prototype.map, Array.prototype.filter, arrow functions, and spread syntax.
See this answer for an example with Array.prototype.map:
let emails = people.map(({ email }) => email);
Original answer:
Yes, JavaScript will support array comprehensions in the upcoming EcmaScript version 7.
Here's an example.
var str = "1234-5";
var ignore = "-";
console.log([for (i of str) if (!ignore.includes(i)) i]);

Given the question's Python code
print([int(i) for i in str(string) if i not in forbidden])
this is the most direct translation to JavaScript (ES2015):
const string = '1234-5';
const forbidden = '-';
console.log([...string].filter(c => !forbidden.includes(c)).map(c => parseInt(c)));
// result: [ 1, 2, 3, 4, 5 ]
Here is a comparison of the Python and JavaScript code elements being used:
(Python -> Javascript):
print -> console.log
unpacking string to list -> spread operator
list comprehension 'if' -> Array.filter
list comprehension 'for' -> Array.map
substr in str? -> string.includes

Reading the code, I assume forbidden can have more than 1 character. I'm also assuming the output should be "12345"
var string = "12=34-5";
var forbidden = "=-";
console.log(string.split("").filter(function(str){
return forbidden.indexOf(str) < 0;
}).join(""))
If the output is "1" "2" "3" "4" "5" on separate lines
var string = "12=34-5";
var forbidden = "=-";
string.split("").forEach(function(str){
if (forbidden.indexOf(str) < 0) {
console.log(str);
}
});

Not directly, but it's not hard to replicate.
var string = "1234-5";
var forbidden = "-";
string.split("").filter(function(str){
if(forbidden.indexOf(str) < 0) {
return str;
}
}).forEach(function(letter) { console.log(letter);});
I guess more directly:
for(var i=0 ; i < str.length ; i++) {
if(forbidden.indexOf(str) < 0) {
console.log(str[i]);
}
}
But there's no built in way to filter in your for loop.

You could easily achieve this behavior using an application functor.
Array.prototype.ap = function(xs) {
return this.reduce((acc, f) => acc.concat(xs.map(f)), [])
}
const result = [x => x +1].ap([2])
console.log(result)

JavaScript no longer supports array comprehensions.
I too was looking for the JavaScript equivalent. Mozilla Developer's Network indicates that this functionality is no longer supported.
The preferred syntax is referenced in the aforementioned link.

For "completeness"-sake, here's a shorter regexp version.
var str = "1234-5";
var ignore = "-=";
console.log(str.replace(new RegExp(ignore.split("").join("|")), "").split(""));
EDIT: To make sure that RegExp does not "choke" on special characters, ignore can be implemented as regexp literal, instead of a string:
var str = "1234-5";
var ignore = /[\+=-]/;
console.log(str.replace(ignore, "").split(""));

It does have a poor mans version
const string = '1234-5'
const forbidden = '-'
print([int(i) for i in str(string) if i not in forbidden])
const result = string.split('').filter(char => char !== forbidden);
console.log(result)
In JS you can only iterate over single elements in array, so no extraction of multiple entries at a time like in Python.
For this particular case you should use a RegExp to filter the string though.

You could have a look at CoffeeScript.
CoffeeScript adds missing features to java-script and allows you to write cleaner, more readable code. https://coffeescript.org/#coffeescript-2
You write a .coffee file and the coffeScript-compiler compiles your coffee file into a JavaScript file. Because the translation into JavaScript happens by compiling, the script should not run any slower.
So your code would look like the following in coffee script:
string = '1234-5'
forbidden = '-'
alert(JSON.stringify(+i for i in string when i isnt forbidden))
Honestly, this is even easier to read then the python counterpart. And it compiles quickly to the fallowing JavaScript:
var forbidden, i, string;
string = '1234-5';
forbidden = '-';
alert(JSON.stringify((function() {
var j, len, results;
results = [];
for (j = 0, len = string.length; j < len; j++) {
i = string[j];
if (i !== forbidden) {
results.push(+i);
}
}
return results;
})()));
You don’t even need to install anything. On their website you can play around with it, and it will show you the translated JavaScript code.

Javascript doesn't need list comprehensions because the map and filter functions work better in the language compared to Python.
In Python:
[int(i) for i in '1234-5' if i != '-']
# is equivalent to the ugly
list(map(lambda _: int(_),filter(lambda _: _!='-','1234-5')))
# so we use list comprehensions
In Javascript, to me this is fine once you're familiar with the syntax:
[...'1234-5'].filter(_=> _!='-').map(_=> parseInt(_))

Related

Is it possible to construct a string in Javascript which has 'variables' built in?

I am working on a PDF with some scripting, and I am applying code to fields using the console and some simple loops to save on repeated efforts. In some cases, I am applying a custom calculation script to a field where one integer needs to change from one field to the next. If all the scripts were the same, I would run this in the debugger console:
var s = "if(this.getField(\"Span A\").value >= 60){\n\
event.value = Math.round(((this.getField(\"Span A\").value*41500 - 1674500)/233));\n\
}else{\n\
event.value = Math.round((this.getField(\"Span A\").value*3500/60));\n\
}";
for (var i = 0; i < this.numFields; i++){
var f = this.getField(getNthFieldName(i));
if(f.name.match(/quant a/i) != null){
var n = f.name.match(/\d/g);
f.setAction("Calculate", s);
}
}
I have many 'Quant' fields, and each group (A, B, etc) will have a similar calculation. The fields are name "Quant A1", "Quant A2" etc. Quant A1 needs to calculate with the input from Span A1.
In the above script, it would be really cool if I could have a variable within the script string that I can pass a value (n) to be plugged in to the string, essentially the same way a function call works.
Is this possible?
Here is my fantasy version of what I imagine it could look like (this is just to further explain my intent; I don't think this would actually work this way):
var s(x) = "if(this.getField(\"Span A\""x").value >= 60){\n\
event.value = Math.round(((this.getField(\"Span A\""x").value*41500 - 1674500)/233));\n\
}else{\n\
event.value = Math.round((this.getField(\"Span A\""x").value*3500/60));\n\
}";
for (var i = 0; i < this.numFields; i++){
var f = this.getField(getNthFieldName(i));
if(f.name.match(/quant a/i) != null){
var n = f.name.match(/\d/g);
f.setAction("Calculate", s(n));
}
}
You could use string litterals if you're useing ES6 and higher.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals?retiredLocale=nl
const greetings = "I'm a variable!";
let string = `Hi! this is a variable: ${greetings}`;
console.log(string);
Otherwise concatenate it with the + operator.
If I understand correctly your question. I think you want to use template literals.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Use backticks instead of " or ' to insert your variables inside a string.
const a ='Cheese'
const b= 'is Delicious'
${a} ${b} will output 'Cheese is Delicious'

Minifying javascript via unicode

on dwitter.net i often see dweets that are encoded interestingly to minify the JS to character count.
for example https://www.dwitter.net/d/22372 (or https://www.dwitter.net/d/11506)
eval(unescape(escape`𮀮𩡯𫡴🐧𜡥𫐠𨐧𛁸𛡦𪑬𫁔𩑸𭀨𙱜𭐲𝠲𜀠𙰬𜰬𜠵𚐊𭀿𜀺𩀽𮀮𩱥𭁉𫑡𩱥𡁡𭁡𚀰𛀰𛁶🐳𝠬𭠩𛡤𨑴𨐊𩡯𬠨𨰮𭱩𩁴𪁼👷👩🐹𜰶𞱩𛐭𞰩𩐽𪐥𭠪𝠬𩁛𪐪𝀫𜱝🠵𜁼𯁸𛡦𪑬𫁒𩑣𭀨𦀽𩐫𩐯𜠪𤰨𭀭𪐯𭰩𚱷𛁩𛰳𛑥𚡃𚁴𛑘𛰹𞐩𚱥𚰵𜀬𞐬𪐼𜐿𭰺𞐩`.replace(/u../g,'')))
Now I understand how to decode this and read the javascript, it's pretty trivial
unescape(escape`𮀮𩡯𫡴🐧𜡥𫐠𨐧𛁸𛡦𪑬𫁔𩑸𭀨𙱜𭐲𝠲𜀠𙰬𜰬𜠵𚐊𭀿𜀺𩀽𮀮𩱥𭁉𫑡𩱥𡁡𭁡𚀰𛀰𛁶🐳𝠬𭠩𛡤𨑴𨐊𩡯𬠨𨰮𭱩𩁴𪁼👷👩🐹𜰶𞱩𛐭𞰩𩐽𪐥𭠪𝠬𩁛𪐪𝀫𜱝🠵𜁼𯁸𛡦𪑬𫁒𩑣𭀨𦀽𩐫𩐯𜠪𤰨𭀭𪐯𭰩𚱷𛁩𛰳𛑥𚡃𚁴𛑘𛰹𞐩𚱥𚰵𜀬𞐬𪐼𜐿𭰺𞐩`.replace(/u../g,''))
returns
x.font='2em a',x.fillText('\u2620 ',3,25)
t?0:d=x.getImageData(0,0,v=36,v).data
for(c.width|=w=i=936;i--;)e=i%v*6,d[i*4+3]>50||x.fillRect(X=e+e/2*S(t-i/w)+w,i/3-e*C(t-X/99)+e+50,9,i<1?w:9)
but what I don't understand is how to encode js like this.
I noticed there is an intermediary step in this process
running:
escape`𮀮𩡯𫡴🐧𜡥𫐠𨐧𛁸𛡦𪑬𫁔𩑸𭀨𙱜𭐲𝠲𜀠𙰬𜰬𜠵𚐊𭀿𜀺𩀽𮀮𩱥𭁉𫑡𩱥𡁡𭁡𚀰𛀰𛁶🐳𝠬𭠩𛡤𨑴𨐊𩡯𬠨𨰮𭱩𩁴𪁼👷👩🐹𜰶𞱩𛐭𞰩𩐽𪐥𭠪𝠬𩁛𪐪𝀫𜱝🠵𜁼𯁸𛡦𪑬𫁒𩑣𭀨𦀽𩐫𩐯𜠪𤰨𭀭𪐯𭰩𚱷𛁩𛰳𛑥𚡃𚁴𛑘𛰹𞐩𚱥𚰵𜀬𞐬𪐼𜐿𭰺𞐩`
returns
%uD878%uDC2E%uD866%uDC6F%uD86E%uDC74%uD83D%uDC27%uD832%uDC65%uD86D%uDC20%uD861%uDC27%uD82C%uDC78%uD82E%uDC66%uD869%uDC6C%uD86C%uDC54%uD865%uDC78%uD874%uDC28%uD827%uDC5C%uD875%uDC32%uD836%uDC32%uD830%uDC20%uD827%uDC2C%uD833%uDC2C%uD832%uDC35%uD829%uDC0A%uD874%uDC3F%uD830%uDC3A%uD864%uDC3D%uD878%uDC2E%uD867%uDC65%uD874%uDC49%uD86D%uDC61%uD867%uDC65%uD844%uDC61%uD874%uDC61%uD828%uDC30%uD82C%uDC30%uD82C%uDC76%uD83D%uDC33%uD836%uDC2C%uD876%uDC29%uD82E%uDC64%uD861%uDC74%uD861%uDC0A%uD866%uDC6F%uD872%uDC28%uD863%uDC2E%uD877%uDC69%uD864%uDC74%uD868%uDC7C%uD83D%uDC77%uD83D%uDC69%uD83D%uDC39%uD833%uDC36%uD83B%uDC69%uD82D%uDC2D%uD83B%uDC29%uD865%uDC3D%uD869%uDC25%uD876%uDC2A%uD836%uDC2C%uD864%uDC5B%uD869%uDC2A%uD834%uDC2B%uD833%uDC5D%uD83E%uDC35%uD830%uDC7C%uD87C%uDC78%uD82E%uDC66%uD869%uDC6C%uD86C%uDC52%uD865%uDC63%uD874%uDC28%uD858%uDC3D%uD865%uDC2B%uD865%uDC2F%uD832%uDC2A%uD853%uDC28%uD874%uDC2D%uD869%uDC2F%uD877%uDC29%uD82B%uDC77%uD82C%uDC69%uD82F%uDC33%uD82D%uDC65%uD82A%uDC43%uD828%uDC74%uD82D%uDC58%uD82F%uDC39%uD839%uDC29%uD82B%uDC65%uD82B%uDC35%uD830%uDC2C%uD839%uDC2C%uD869%uDC3C%uD831%uDC3F%uD877%uDC3A%uD839%uDC29
which then gets regex replaced with .replace(/u../g,''), but getting this string from minified javascript isn't easy for me.
simply running encodeURIComponent() or escape() doesn't get you quite there, though it gets you part of the way there.
So how do I get the string of my javascript converted into a string containing %uD then the character code for each?
I am also on dwitter.
The code compressor actually began with a dweet (https://www.dwitter.net/d/23092).
It was made so people could add more bytes into their demos by going right up to 194 chars instead of having the limit of 140.
Note this does not reduce the byte size.
Even though this reduces the amount of characters, the size stays the same
There is also an uncompressor at https://www.dwitter.net/d/14246
The simplified code for this is a simple unpack function:
function unpack(strange_blocky_code) {
const index = code.toLowerCase().search(/eval\(unescape\(escape`/g)
if (index >= 0) {
const start = strange_blocky_code.slice(0, index)
const end = strange_blocky_code.slice(index)
const result = eval(end.slice(4))
if (result) return start + result // returns readable (but trivial) code
}
}
The simplified compressing code is:
function compress(readable_code) {
const value = [...readable_code.trim()]
let code = ''
for (let character of value) {
const char = character.charCodeAt(0)
if (char > 255) character = escape(character).replace(/%u/g, "\\u")
code += character
}
const compressed =
String.fromCharCode(...[...code.length % 2 ? code + ";" : code]
.map((item, index) =>
item.charCodeAt() | (index % 2 ? 0xDF00 : 0xDB00)
)
)
return `eval(unescape(escape\`${compressed}\`.replace(/u../g,'')))`
}
If you're looking for editors, these are two that I like to use:
https://greyhope.uk/Dweet-Runner/index.html made by GreyHope
https://dweetabase.3d2k.com/ made by Frank Force
I hope this helps at all.

Number formatting in template strings (Javascript - ES6)

I was wondering if it is possible to format numbers in Javascript template strings, for example something like:
var n = 5.1234;
console.log(`This is a number: $.2d{n}`);
// -> 5.12
Or possibly
var n = 5.1234;
console.log(`This is a number: ${n.toString('.2d')}`);
// -> 5.12
That syntax obviously doesn't work, it is just an illustration of the type of thing I'm looking for.
I am aware of tools like sprintf from underscore.string, but this seems like something that JS should be able to do out the box, especially given the power of template strings.
EDIT
As stated above, I am already aware of 3rd party tools (e.g. sprintf) and customised functions to do this. Similar questions (e.g. JavaScript equivalent to printf/String.Format) don't mention template strings at all, probably because they were asked before the ES6 template strings were around. My question is specific to ES6, and is independent of implementation. I am quite happy to accept an answer of "No, this is not possible" if that is case, but what would be great is either info about a new ES6 feature that provides this, or some insight into whether such a feature is on its way.
No, ES6 does not introduce any new number formatting functions, you will have to live with the existing .toExponential(fractionDigits), .toFixed(fractionDigits), .toPrecision(precision), .toString([radix]) and toLocaleString(…) (which has been updated to optionally support the ECMA-402 Standard, though).
Template strings have nothing to do with number formatting, they just desugar to a function call (if tagged) or string concatenation (default).
If those Number methods are not sufficient for you, you will have to roll your own. You can of course write your formatting function as a template string tag if you wish to do so.
You should be able to use the toFixed() method of a number:
var num = 5.1234;
var n = num.toFixed(2);
If you want to use ES6 tag functions here's how such a tag function would look,
function d2(pieces) {
var result = pieces[0];
var substitutions = [].slice.call(arguments, 1);
for (var i = 0; i < substitutions.length; ++i) {
var n = substitutions[i];
if (Number(n) == n) {
result += Number(substitutions[i]).toFixed(2);
} else {
result += substitutions[i];
}
result += pieces[i + 1];
}
return result;
}
which can then be applied to a template string thusly,
d2`${some_float} (you can interpolate as many floats as you want) of ${some_string}`;
that will format the float and leave the string alone.
Here's a fully ES6 version of Filip Allberg's solution above, using ES6 "rest" params. The only thing missing is being able to vary the precision; that could be done by making a factory function. Left as an exercise for the reader.
function d2(strs, ...args) {
var result = strs[0];
for (var i = 0; i < args.length; ++i) {
var n = args[i];
if (Number(n) == n) {
result += Number(args[i]).toFixed(2);
} else {
result += args[i];
}
result += strs[i+1];
}
return result;
}
f=1.2345678;
s="a string";
console.log(d2`template: ${f} ${f*100} and ${s} (literal:${9.0001})`);
While template-string interpolation formatting is not available as a built-in, you can get equivalent behavior with Intl.NumberFormat:
const format = (num, fraction = 2) => new Intl.NumberFormat([], {
minimumFractionDigits: fraction,
maximumFractionDigits: fraction,
}).format(num);
format(5.1234); // -> '5.12'
Note that regardless of your implementation of choice, you might get bitten by rounding errors:
(9.999).toFixed(2) // -> '10.00'
new Intl.NumberFormat([], {
minimumFractionDigits: 2,
maximumFractionDigits: 2, // <- implicit rounding!
}).format(9.999) // -> '10.00'
based on ES6 Tagged Templates (credit to https://stackoverflow.com/a/51680250/711085), this will emulate typical template string syntax in other languages (this is loosely based on python f-strings; I avoid calling it f in case of name overlaps):
Demo:
> F`${(Math.sqrt(2))**2}{.0f}` // normally 2.0000000000000004
"2"
> F`${1/3}{%} ~ ${1/3}{.2%} ~ ${1/3}{d} ~ ${1/3}{.2f} ~ ${1/3}"
"33% ~ 33.33% ~ 0 ~ 0.33 ~ 0.3333333333333333"
> F`${[1/3,1/3]}{.2f} ~ ${{a:1/3, b:1/3}}{.2f} ~ ${"someStr"}`
"[0.33,0.33] ~ {\"a\":\"0.33\",\"b\":\"0.33\"} ~ someStr
Fairly simple code using :
var FORMATTER = function(obj,fmt) {
/* implements things using (Number).toFixed:
${1/3}{.2f} -> 0.33
${1/3}{.0f} -> 1
${1/3}{%} -> 33%
${1/3}{.3%} -> 33.333%
${1/3}{d} -> 0
${{a:1/3,b:1/3}}{.2f} -> {"a":0.33, "b":0.33}
${{a:1/3,b:1/3}}{*:'.2f',b:'%'} -> {"a":0.33, "b":'33%'} //TODO not implemented
${[1/3,1/3]}{.2f} -> [0.33, 0.33]
${someObj} -> if the object/class defines a method [Symbol.FTemplate](){...},
it will be evaluated; alternatively if a method [Symbol.FTemplateKey](key){...}
that can be evaluated to a fmt string; alternatively in the future
once decorators exist, metadata may be appended to object properties to derive
formats //TODO not implemented
*/
try {
let fracDigits=0,percent;
if (fmt===undefined) {
if (typeof obj === 'string')
return obj;
else
return JSON.stringify(obj);
} else if (obj instanceof Array)
return '['+obj.map(x=> FORMATTER(x,fmt))+']'
else if (typeof obj==='object' && obj!==null /*&&!Array.isArray(obj)*/)
return JSON.stringify(Object.fromEntries(Object.entries(obj).map(([k,v])=> [k,FORMATTER(v,fmt)])));
else if (matches = fmt.match(/^\.(\d+)f$/))
[_,fracDigits] = matches;
else if (matches = fmt.match(/^(?:\.(\d+))?(%)$/))
[_,fracDigits,percent] = matches;
else if (matches = fmt.match(/^d$/))
fracDigits = 0;
else
throw 'format not recognized';
if (obj===null)
return 'null';
if (obj===undefined) {
// one might extend the above syntax to
// allow for example for .3f? -> "undefined"|"0.123"
return 'undefined';
}
if (percent)
obj *= 100;
fracDigits = parseFloat(fracDigits);
return obj.toFixed(fracDigits) + (percent? '%':'');
} catch(err) {
throw `error executing F\`$\{${someObj}\}{${fmt}}\` specification: ${err}`
}
}
function F(strs, ...args) {
/* usage: F`Demo: 1+1.5 = ${1+1.5}{.2f}`
--> "Demo: 1+1.5 = 2.50"
*/
let R = strs[0];
args.forEach((arg,i)=> {
let [_,fmt,str] = strs[i+1].match(/(?:\{(.*)(?<!\\)\})?(.*)/);
R += FORMATTER(arg,fmt) + str;
});
return R;
}
sidenote: The core of the code is as follows. The heavy lifting is done by the formatter. The negative lookbehind is somewhat optional, and to let one escape actual curly braces.
let R = strs[0];
args.forEach((arg,i)=> {
let [_,fmt,str] = strs[i+1].match(/(?:\{(.*)(?<!\\)\})?(.*)/);
R += FORMATTER(arg,fmt) + str;
});
You can use es6 tag functions. I don't know ready for use of that.
It might look like this:
num`This is a number: $.2d{n}`
Learn more:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings

jQuery / JavaScript Parsing strings the proper way

Recently, I've been attempting to emulate a small language in jQuery and JavaScript, yet I've come across what I believe is an issue. I think that I may be parsing everything completely wrong.
In the code:
#name Testing
#inputs
#outputs
#persist
#trigger
print("Test")
The current way I am separating and parsing the string is by splitting all of the code into lines, and then reading through this lines array using searches and splits. For example, I would find the name using something like:
if(typeof lines[line] === 'undefined')
{
}
else
{
if(lines[line].search('#name') == 0)
{
name = lines[line].split(' ')[1];
}
}
But I think that I may be largely wrong on how I am handling parsing.
While reading through examples on how other people are handling parsing of code blocks like this, it appeared that people parsed the entire block, instead of splitting it into lines as I do. I suppose the question of the matter is, what is the proper and conventional way of parsing things like this, and how do you suggest I use it to parse something such as this?
In simple cases like this regular expressions is your tool of choice:
matches = code.match(/#name\s+(\w+)/)
name = matches[1]
To parse "real" programming languages regexps are not powerful enough, you'll need a parser, either hand-written or automatically generated with a tool like PEG.
A general approach to parsing, that I like to take often is the following:
loop through the complete block of text, character by character.
if you find a character that signalizes the start of one unit, call a specialized subfunction to parse the next characters.
within each subfunction, call additional subfunctions if you find certain characters
return from every subfunction when a character is found, that signalizes, that the unit has ended.
Here is a small example:
var text = "#func(arg1,arg2)"
function parse(text) {
var i, max_i, ch, funcRes;
for (i = 0, max_i = text.length; i < max_i; i++) {
ch = text.charAt(i);
if (ch === "#") {
funcRes = parseFunction(text, i + 1);
i = funcRes.index;
}
}
console.log(funcRes);
}
function parseFunction(text, i) {
var max_i, ch, name, argsRes;
name = [];
for (max_i = text.length; i < max_i; i++) {
ch = text.charAt(i);
if (ch === "(") {
argsRes = parseArguments(text, i + 1);
return {
name: name.join(""),
args: argsRes.arr,
index: argsRes.index
};
}
name.push(ch);
}
}
function parseArguments(text, i) {
var max_i, ch, args, arg;
arg = [];
args = [];
for (max_i = text.length; i < max_i; i++) {
ch = text.charAt(i);
if (ch === ",") {
args.push(arg.join(""));
arg = [];
continue;
} else if (ch === ")") {
args.push(arg.join(""));
return {
arr: args,
index: i
};
}
arg.push(ch);
}
}
FIDDLE
this example just parses function expressions, that follow the syntax "#functionName(argumentName1, argumentName2, ...)". The general idea is to visit every character exactly once without the need to save current states like "hasSeenAtCharacter" or "hasSeenOpeningParentheses", which can get pretty messy when you parse large structures.
Please note that this is a very simplified example and it misses all the error handling and stuff like that, but I hope the general idea can be seen. Note also that I'm not saying that you should use this approach all the time. It's a very general approach, that can be used in many scenerios. But that doesn't mean that it can't be combined with regular expressions for instance, if it, at some part of your text, makes more sense than parsing each individual character.
And one last remark: you can save yourself the trouble if you put the specialized parsing function inside the main parsing function, so that all functions have access to the same variable i.

Compare mscrm GUIDs in js

Is there some better/official way, how to compare CRM 2011 GUIDs in JavaScript
2e9565c4-fc5b-e211-993c-000c29208ee5=={2E9565C4-FC5B-E211-993C-000C29208EE5}
without using .replace() and .toLowerCase()?
First one is got thru XMLHttpRequest/JSON:
JSON.parse(r.responseText).d.results[0].id
Second one is got from form:
Xrm.Page.getAttribute("field").getValue()[0].id
There is no official way to compare GUIDs in JavaScript because there is no primitive GUID type. Thus you should treat GUIDs as strings.
If you must not use replace() and toLowerCase() you can use a regular expression:
// "i" is for ignore case
var regExp = new RegExp("2e9565c4-fc5b-e211-993c-000c29208ee5", "i");
alert(regExp.test("{2E9565C4-FC5B-E211-993C-000C29208EE5}"));
It would probably be slower than replace/toLowerCase().
You can use the node-uuid (https://github.com/broofa/node-uuid) library and do a byte comparison after parsing the strings into bytes. The bytes are returned as arrays and can be compared using the lodash _.difference method. This will handle cases where the GUID's aren't using the same case or if they don't have '-' dashes.
Coffeescript:
compareGuids: (guid1, guid2) ->
bytes1 = uuid.parse(guid1)
bytes2 = uuid.parse(guid2)
# difference returns [] for equal arrays
difference = _.difference(bytes1, bytes2)
return difference.length == 0
Javascript (update):
compareGuids: function(guid1, guid2) {
var bytes1, bytes2, difference;
bytes1 = uuid.parse(guid1);
bytes2 = uuid.parse(guid2);
difference = _.difference(bytes1, bytes2);
return difference.length === 0;
}
var rgx = /[\{\-\}]/g;
function _guidsAreEqual(left, right) {
var txtLeft = left.replace(rgx, '').toUpperCase();
var txtRight = right.replace(rgx, '').toUpperCase();
return txtLeft === txtRight;
};

Categories