App version compare with different version format - javascript

Need some help regarding a small bit of code which needs some expert advice. It is a code I wrote on my own for comparing versions of an application with that of app store version. It has some small flaw but I couldn't move forward with it. Any help will be greatly valuable.
function versionCompare(appVersionInStore, appVersionInReq) {
var versionStoreArray = appVersionInStore.split('.');
var versionReqArray = appVersionInReq.split('.');
var arrIndex;
var len = Math.max(versionStoreArray.length, versionReqArray.length);
for (var i = 0; i < versionStoreArray.length; i++) {
if (versionStoreArray[i].length < 2) {
versionStoreArray[i] = '0' + versionStoreArray[i];
}
}
for (var i = 0; i < versionReqArray.length; i++) {
if (versionReqArray[i].length < 2) {
versionReqArray[i] = '0' + versionReqArray[i];
}
}
appVersionInStore = versionStoreArray.join('');
appVersionInReq = versionReqArray.join('');
appVersionInStore = parseInt(appVersionInStore);
appVersionInReq = parseInt(appVersionInReq);
var result = appVersionInStore - appVersionInReq;
return result;
}
var versionDifference = versionCompare('3.1.2', '3.1.7');
if (versionDifference >= 4) {
appUpdatePolicy = 'MANDATORY';
} else if ((versionDifference >= 1) && (versionDifference <= 3)) {
appUpdatePolicy = 'OPTIONAL';
} else if ((versionDifference <= 0)) {
appUpdatePolicy = 'NONE';
}
return appUpdatePolicy;
This is returning appUpdatePolicy with three values - MNADATORY, OPTIONAL, OR NONE based on the versionCompare() function. Now if the version are in similar format(3.1.1 - 2 decimal or 17.2 - 1 decimal) and are being compared, its working fine. If they are not in similar format (3.1.2 being compared with 17.2), it's not working fine. Any helps on this?
We have a use case where in the version can be in different format possibly.

Related

How to improve the speed of a for loop

I'm using Datatables and Highcharts for a reporting screen but it is quite slow to load the chart (approx 10 Seconds), using performance.now() I can see the segment below is causing the delay:
Please note, the 'indexes' array contains 6500+ records.
var monthTO = {};
var indexes = TurnoverRepoTable.rows({ search: 'applied' }).indexes().toArray();
for (var i = 0; i < indexes.length; i++) {
var cMonth = TurnoverRepoTable.cell(indexes[i], 2).data();
var value = TurnoverRepoTable.cell(indexes[i], 6).data();
if (monthTO[cMonth] === undefined) {
monthTO[cMonth] = Number(value);
} else {
monthTO[cMonth] = monthTO[cMonth] + Number(value);
}
}
So, I'd like to know if there a more efficient way of achieving this?
Cheers, Chris
Hi,
I have solved this issue by referencing the data directly (not by using the indexes), code below:
var dataset = TurnoverRepoTable.rows({ search: 'applied' }).data().toArray();
// For each row, extract the office and add the salary to the array
for (var i = 0; i < dataset.length; i++) {
var cMonth = dataset[i].job.cMonth
var value = dataset[i].job.estout
if (monthTO[cMonth] === undefined) {
monthTO[cMonth] = Number(value);
} else {
monthTO[cMonth] = monthTO[cMonth] + Number(value);
}
}

javascript multiple AND conditions in IF statement inside for loop javascript

I feel stupid because I´m stuck with a basic. I have three set of classes that contains paragraphs and I want to change the background color of each one depending on day (with New Dat.getDay().
I dont know how to mix for loop and if statements for each set of classes correctly. I guess it´s something simple but I missing it!
function changecolor() {
var d = new Date();
var n = d.getDay();
var weekda = document.getElementsByClassName('weekdays');
var sat = document.getElementsByClassName('saturday');
var dom = document.getElementsByClassName('sun-fer');
for (var i = 0; i < weekda.length && i < sat.length && i < dom.length; i++)
if (n > 0 || n < 6) {
weekda[i].setAttribute("style", "background-color:#0091ea;color:white;");
}
else if (n == 6) {
sat[i].setAttribute("style", "background-color:#0091ea;color:white;");
} else {
dom[i].setAttribute("style", "background-color:#0091ea;color:white;");
}
}
}
changecolor();
You need to group conditions. Read more about Operator precedence
for (var i = 0;( (i < weekda.length) && (i < sat.length) && (i < dom.length)); i++){
// your code
}
Part of the problem may be you have background-color:#0091ea;color:white; for all three options. Therefore you may not be seeing any change.
Personally I would break this up a little to make it more flexible and a little easier to read (and maintain). For example:
function changecolor() {
var d = new Date();
var e = null;
var s = null;
switch(d.getDay()) {
case 6:
e = document.getElementsByClassName('saturday');
s = "background-color:#0091ea;color:white;";
break;
case 0:
e = document.getElementsByClassName('sun-fer');
s = "background-color:#0091ea;color:green;";
break;
default:
e = document.getElementsByClassName('weekdays');
s = "background-color:#0091ea;color:blue;";
}
// now update the color
updateItem(e,s);
}
function updateItem(e,s) {
var i, max = e.length;
for(i=0;i<max;i++) {
e[i].setAttribute("style",s);
}
}

Newtons Method In JS Being Inaccurate

So, I am trying to write a js function that takes 3 inputs (polynomial, guess and limit) and make them return the approximate root of the polynomial. The problem is that, even with a limit of 1000, the result is still very inaccurate. Does anybody have any ideas on why this may be?
The Method
The code:
var derivativeOfATerm = function(arr) {
var one = arr[0];
var two = arr[1];
var derivative = [];
if (two <= 0) {
return [0, 0];
} else {
derivative.push(one * two);
derivative.push(two - 1);
return derivative;
}
};
var derivativeOfPolynomial = function(arr, order = 1) {
var derivative = [];
for (var i = 0; i < arr.length; i++) {
//console.log(arr[i]);
derivative.push(derivativeOfATerm(arr[i]));
}
if (order === 1) {
return derivative;
} else {
return derivativeOfPolynomial(derivative, order - 1);
}
};
var runPolynomial = function(poly, num) {
var array = [];
for (var i = 0; i < poly.length; i++) {
array.push(Math.pow(num, poly[i][1]) * poly[i][0]);
}
return array.reduce((a, b) => a + b);
};
var newtonRootFind = function(polynomial, guess, limit = 10) {
var derivative = derivativeOfPolynomial(polynomial);
var previous = guess;
var next;
for (var i = 0; i < limit; i++) {
next = previous - (runPolynomial(polynomial, previous)) / (runPolynomial(derivative, previous));
previous = next;
console.log("%o : x=%o, p(x)=%o", i+1, next, runPolynomial(polynomial, next));
}
return previous;
};
console.log("result x=",newtonRootFind([[1,2],[1,1],[-5,0]], 5, 10));
I'm only 12 so try not to use that many technical terms.
For example, entering [[1,2],[1,1],[-5,0]] or x^2+x-5, it returns 1.79128784747792, which isn't accurate enough. It equals 4.79... when it should be very close to 5.
As worked out in the comments, the presented code works as intended, the problem was that in checking the solution x^2 was used for the square x*x.
However, x^y in most C- or Java-like languages is the bitwise "exclusive or", XOR, not the power operation. x^y as symbol for the power operation is usually found in Computer Algebra Systems. Script languages as python or gnuplot tend to use x**y.

Text area transposition

I am a beginner and I've found some useful examples for what I want to do. The problem is the examples that I've found don't have enough comments for me to understand what is going on. So, I hope someone can help me implement the code I've found into the code that I already have. I'm making a text manipulation area to use to play with cipher text. It's all being done inside a single HTML text area. I've got a functions called, "function G_Group(size, count)", that breaks the text into rows and columns of choice and it is working great. The next tool that I want to add will transpose this matrix from (x,y) to (y,x). Because I have the "function G-Group" function, I don't believe I need to slice anything. I found a bit of JavaScript transposition code at http://rosettacode.org/wiki/Matrix_transposition#JavaScript but I don't know how to change the values to add it to what I've got already.
Function G_Group(size, count) is called like this.
<input type= button value="Grouping" onclick = "return G_Group(0, 0)" title="grouping" />
And here is the how i break text up into rows and columns:
function G_Group(size, count)
{
if (size <= 0)
{
size = document.encoder.group_size.value;
if (size <= 0)
{
alert('Invalid group size');
return false;
}
}
if (count <= 0)
{
count = document.encoder.group_count.value;
if (count <= 0)
{
alert('Invalid group count');
return false;
}
}
var t = document.encoder.text.value;
var o = '', groups = 0;
t = Tr(t, " \r\n\t");
while (t.length > 0)
{
if (o.length > 0)
{
o += ' ';
}
if (groups >= count)
{
o += "\n";
groups = 0;
}
groups ++;
o += t.slice(0, size);
t = t.slice(size, t.length);
}
document.encoder.text.value = o;
return false;
}
And this is the code that I want modify to transpose the array.
function Matrix(ary) {
this.mtx = ary
this.height = ary.length;
this.width = ary[0].length;
}
Matrix.prototype.toString = function() {
var s = []
for (var i = 0; i < this.mtx.length; i++)
s.push( this.mtx[i].join(",") );
return s.join("\n");
}
// returns a new matrix
Matrix.prototype.transpose = function() {
var transposed = [];
for (var i = 0; i < this.width; i++) {
transposed[i] = [];
for (var j = 0; j < this.height; j++) {
transposed[i][j] = this.mtx[j][i];
}
}
return new Matrix(transposed);
}
I am aware that I may be approaching this all wrong. And I'm aware that the questions I have are very basic, I'm a little embarrassed to ask these simple questions. Please excuse me. I'm 43 years old and had c programming in college 20 years ago. I'm pretty good with HTML and CSS but I'm lacking in a lot of areas. Hope someone can help me with this. Thanks.

JavaScript strings outside of the BMP

BMP being Basic Multilingual Plane
According to JavaScript: the Good Parts:
JavaScript was built at a time when Unicode was a 16-bit character set, so all characters in JavaScript are 16 bits wide.
This leads me to believe that JavaScript uses UCS-2 (not UTF-16!) and can only handle characters up to U+FFFF.
Further investigation confirms this:
> String.fromCharCode(0x20001);
The fromCharCode method seems to only use the lowest 16 bits when returning the Unicode character. Trying to get U+20001 (CJK unified ideograph 20001) instead returns U+0001.
Question: is it at all possible to handle post-BMP characters in JavaScript?
2011-07-31: slide twelve from Unicode Support Shootout: The Good, The Bad, & the (mostly) Ugly covers issues related to this quite well:
Depends what you mean by ‘support’. You can certainly put non-UCS-2 characters in a JS string using surrogates, and browsers will display them if they can.
But, each item in a JS string is a separate UTF-16 code unit. There is no language-level support for handling full characters: all the standard String members (length, split, slice etc) all deal with code units not characters, so will quite happily split surrogate pairs or hold invalid surrogate sequences.
If you want surrogate-aware methods, I'm afraid you're going to have to start writing them yourself! For example:
String.prototype.getCodePointLength= function() {
return this.length-this.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g).length+1;
};
String.fromCodePoint= function() {
var chars= Array.prototype.slice.call(arguments);
for (var i= chars.length; i-->0;) {
var n = chars[i]-0x10000;
if (n>=0)
chars.splice(i, 1, 0xD800+(n>>10), 0xDC00+(n&0x3FF));
}
return String.fromCharCode.apply(null, chars);
};
I came to the same conclusion as bobince. If you want to work with strings containing unicode characters outside of the BMP, you have to reimplement javascript's String methods. This is because javascript counts characters as each 16-bit code value. Symbols outside of the BMP need two code values to be represented. You therefore run into a case where some symbols count as two characters and some count only as one.
I've reimplemented the following methods to treat each unicode code point as a single character: .length, .charCodeAt, .fromCharCode, .charAt, .indexOf, .lastIndexOf, .splice, and .split.
You can check it out on jsfiddle: http://jsfiddle.net/Y89Du/
Here's the code without comments. I tested it, but it may still have errors. Comments are welcome.
if (!String.prototype.ucLength) {
String.prototype.ucLength = function() {
// this solution was taken from
// http://stackoverflow.com/questions/3744721/javascript-strings-outside-of-the-bmp
return this.length - this.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g).length + 1;
};
}
if (!String.prototype.codePointAt) {
String.prototype.codePointAt = function (ucPos) {
if (isNaN(ucPos)){
ucPos = 0;
}
var str = String(this);
var codePoint = null;
var pairFound = false;
var ucIndex = -1;
var i = 0;
while (i < str.length){
ucIndex += 1;
var code = str.charCodeAt(i);
var next = str.charCodeAt(i + 1);
pairFound = (0xD800 <= code && code <= 0xDBFF && 0xDC00 <= next && next <= 0xDFFF);
if (ucIndex == ucPos){
codePoint = pairFound ? ((code - 0xD800) * 0x400) + (next - 0xDC00) + 0x10000 : code;
break;
} else{
i += pairFound ? 2 : 1;
}
}
return codePoint;
};
}
if (!String.fromCodePoint) {
String.fromCodePoint = function () {
var strChars = [], codePoint, offset, codeValues, i;
for (i = 0; i < arguments.length; ++i) {
codePoint = arguments[i];
offset = codePoint - 0x10000;
if (codePoint > 0xFFFF){
codeValues = [0xD800 + (offset >> 10), 0xDC00 + (offset & 0x3FF)];
} else{
codeValues = [codePoint];
}
strChars.push(String.fromCharCode.apply(null, codeValues));
}
return strChars.join("");
};
}
if (!String.prototype.ucCharAt) {
String.prototype.ucCharAt = function (ucIndex) {
var str = String(this);
var codePoint = str.codePointAt(ucIndex);
var ucChar = String.fromCodePoint(codePoint);
return ucChar;
};
}
if (!String.prototype.ucIndexOf) {
String.prototype.ucIndexOf = function (searchStr, ucStart) {
if (isNaN(ucStart)){
ucStart = 0;
}
if (ucStart < 0){
ucStart = 0;
}
var str = String(this);
var strUCLength = str.ucLength();
searchStr = String(searchStr);
var ucSearchLength = searchStr.ucLength();
var i = ucStart;
while (i < strUCLength){
var ucSlice = str.ucSlice(i,i+ucSearchLength);
if (ucSlice == searchStr){
return i;
}
i++;
}
return -1;
};
}
if (!String.prototype.ucLastIndexOf) {
String.prototype.ucLastIndexOf = function (searchStr, ucStart) {
var str = String(this);
var strUCLength = str.ucLength();
if (isNaN(ucStart)){
ucStart = strUCLength - 1;
}
if (ucStart >= strUCLength){
ucStart = strUCLength - 1;
}
searchStr = String(searchStr);
var ucSearchLength = searchStr.ucLength();
var i = ucStart;
while (i >= 0){
var ucSlice = str.ucSlice(i,i+ucSearchLength);
if (ucSlice == searchStr){
return i;
}
i--;
}
return -1;
};
}
if (!String.prototype.ucSlice) {
String.prototype.ucSlice = function (ucStart, ucStop) {
var str = String(this);
var strUCLength = str.ucLength();
if (isNaN(ucStart)){
ucStart = 0;
}
if (ucStart < 0){
ucStart = strUCLength + ucStart;
if (ucStart < 0){ ucStart = 0;}
}
if (typeof(ucStop) == 'undefined'){
ucStop = strUCLength - 1;
}
if (ucStop < 0){
ucStop = strUCLength + ucStop;
if (ucStop < 0){ ucStop = 0;}
}
var ucChars = [];
var i = ucStart;
while (i < ucStop){
ucChars.push(str.ucCharAt(i));
i++;
}
return ucChars.join("");
};
}
if (!String.prototype.ucSplit) {
String.prototype.ucSplit = function (delimeter, limit) {
var str = String(this);
var strUCLength = str.ucLength();
var ucChars = [];
if (delimeter == ''){
for (var i = 0; i < strUCLength; i++){
ucChars.push(str.ucCharAt(i));
}
ucChars = ucChars.slice(0, 0 + limit);
} else{
ucChars = str.split(delimeter, limit);
}
return ucChars;
};
}
More recent JavaScript engines have String.fromCodePoint.
const ideograph = String.fromCodePoint( 0x20001 ); // outside the BMP
Also a code-point iterator, which gets you the code-point length.
function countCodePoints( str )
{
const i = str[Symbol.iterator]();
let count = 0;
while( !i.next().done ) ++count;
return count;
}
console.log( ideograph.length ); // gives '2'
console.log( countCodePoints(ideograph) ); // '1'
Yes, you can. Although support to non-BMP characters directly in source documents is optional according to the ECMAScript standard, modern browsers let you use them. Naturally, the document encoding must be properly declared, and for most practical purposes you would need to use the UTF-8 encoding. Moreover, you need an editor that can handle UTF-8, and you need some input method(s); see e.g. my Full Unicode Input utility.
Using suitable tools and settings, you can write var foo = '𠀁'.
The non-BMP characters will be internally represented as surrogate pairs, so each non-BMP character counts as 2 in the string length.
Using for (c of this) instruction, one can make various computations on a string that contains non-BMP characters. For instance, to compute the string length, and to get the nth character of the string:
String.prototype.magicLength = function()
{
var c, k;
k = 0;
for (c of this) // iterate each char of this
{
k++;
}
return k;
}
String.prototype.magicCharAt = function(n)
{
var c, k;
k = 0;
for (c of this) // iterate each char of this
{
if (k == n) return c + "";
k++;
}
return "";
}
This old topic has now a simple solution in ES6:
Split characters into an array
simple version
[..."😴😄😃⛔🎠🚓🚇"] // ["😴", "😄", "😃", "⛔", "🎠", "🚓", "🚇"]
Then having each one separated you can handle them easily for most common cases.
Credit: DownGoat
Full solution
To overcome special emojis as the one in the comment, one can search for the connection charecter (char code 8205 in UTF-16) and make some modifications. Here is how:
let myStr = "👩‍👩‍👧‍👧😃𝌆"
let arr = [...myStr]
for (i = arr.length-1; i--; i>= 0) {
if (arr[i].charCodeAt(0) == 8205) { // special combination character
arr[i-1] += arr[i] + arr[i+1]; // combine them back to a single emoji
arr.splice(i, 2)
}
}
console.log(arr.length) //3
Haven't found a case where this doesn't work. Comment if you do.
To conclude
it seems that JS uses the 8205 char code to represent UCS-2 characters as a UTF-16 combinations.

Categories

Resources