For example if we have string str and I copy it it will be str_1, str_2, str_3 and so on..
If I copy str_2 then it will be str_2_1, str_2_2 and so on.
I have following logic but it does not work..
It should return 'Test2_5' (because Test2 AND Test2_4 already exists) but it returns 'Test2_4'
function createName(nameToCopy) {
var i;
var version = 1;
var nameCopiesArr = ["Test2", "Test2_2",
"Test2_3",
"Test2_4",
"Test2_2_2",
"Test2_3_1",
"Test2_2_1_2",
"Test2_2_3"
];
if (nameCopiesArr && nameCopiesArr.length > 1) {
for (i = 0; i < nameCopiesArr.length; i++) {
var indexes = nameCopiesArr[i].lastIndexOf('_') ? nameCopiesArr[i].match(/\d+$/) : 0
if (indexes) {
version = indexes[indexes.length - 1];
version = parseInt(version) + 1;
}
}
}
p = nameToCopy + '_' + version;
document.getElementById("demo").innerHTML = p;
return p;
}
<button onclick="createName('Test2')">Click me</button>
<p id="demo"></p>
You could search for all string which starts with the given name and a dash and an ending number. Then take the max number of ending and return the given string with an incremented version.
function createName(nameToCopy) {
var copies = ["Test2", "Test2_2", "Test2_3", "Test2_4", "Test2_2_2", "Test2_3_1", "Test2_2_1_2", "Test2_2_3"],
filtered = copies.filter(/./.test.bind(new RegExp(nameToCopy + '_' + '\\d+$'))),
version = filtered.reduce((v, s) => Math.max(v, +s.match(/\d+$/)[0]), 0);
return nameToCopy + '_' + ++version;
}
console.log(['Test2', 'Test', 'Test2_2'].map(createName));
More traditional
function createName(nameToCopy) {
var copies = ["Test2", "Test2_2", "Test2_3", "Test2_4", "Test2_2_2", "Test2_3_1", "Test2_2_1_2", "Test2_2_3"],
regexp = new RegExp(nameToCopy + '_' + '\\d+$'),
version = 0,
i, v;
for (i = 0; i < copies.length; i++) {
if (regexp.test(copies[i])) {
v = +copies[i].match(/\d+$/)[0];
if (v > version) {
version = v;
}
}
}
return nameToCopy + '_' + (version + 1);
}
console.log(['Test2', 'Test', 'Test2_2'].map(createName));
I update your code to test the number of the '_' char and if the current string contains the given input.
function createName(nameToCopy) {
var i;
var version = 1;
var nameToCopy_Nb = (nameToCopy.match(/_/g) || []).length; //number of the '_' char
var nameCopiesArr = ["Test2", "Test2_2",
"Test2_3",
"Test2_4",
"Test2_2_2",
"Test2_3_1",
"Test2_2_1_2",
"Test2_2_3"
];
if (nameCopiesArr && nameCopiesArr.length > 1) {
for (i = 0; i < nameCopiesArr.length; i++) {
var item_Nb = (nameCopiesArr[i].match(/_/g) || []).length;//number of the '_' char
if (nameCopiesArr[i].indexOf(nameToCopy) !== -1 && item_Nb === nameToCopy_Nb + 1) {
var indexes = nameCopiesArr[i].lastIndexOf('_') ? nameCopiesArr[i].match(/\d+$/) : 0
if (indexes) {
version = indexes[indexes.length - 1];
version = parseInt(version) + 1;
}
}
}
}
p = nameToCopy + '_' + version;
document.getElementById("demo").innerHTML = p;
return p;
}
But the answer of #Nina is good and probably the shortest !!! (I upvote her answer)
JSFiddle
I'm not sure what you're trying to do here, or why, so I can't really comment on your code. Just note that it is not too efficient, and not too understandable. And as a side note, your html doesn't call the code you wrote.
to answer your question of why it returns 'Test2_4' : your code loops through the hard coded values you put into the nameCopiesArr, and the version variable keeps the number of the current name + 1. And then you overwrite this with the result from the next entry in the array. Since the last entry in the array is 'Test2_2_3', you grab the last number there - which is 3 - and add 1 to that, so after your last iteration the version variable holds the value of 4 - and this is what you return.
Related
I have a large text from which I read data according to the scheme. Key words are placed in the "smallArtName" array. The scheme looks like this:
(key word) xxx (cordX|cordY)
I can't convert the string I received to a number. It seems to me that the reason is white space, visible in the terminal in the picture. I tried to use the replace method which works for sample text, but not for my value.
I'm a beginner and I could probably do it simpler, but the code I wrote works, and this is the most important thing for now.
for (i = 0; i < smallArtName.length; i++) {
var n = art.artPrintScreen.indexOf(smallArtName[i]);
if (n > 0) {
var tempString = art.artPrintScreen.substring(n, n + 100);
betweenChar = tempString.indexOf('|');
for (k = betweenChar - 10; k <= betweenChar + 10; k++) {
if (tempString[k] == '(') {
xStart = k;
}
if (tempString[k] == ')') {
yEnd = k;
}
}
cordX = tempString.slice(xStart + 1, betweenChar);
cordY = tempString.slice(betweenChar + 1, yEnd);
strTest = " t est".replace(/\s/g, '')
var cordY2 = cordY.replace(/\s/g, '')
console.log(typeof (cordY))
console.log(cordY2)
console.log(cordY2[0])
console.log(cordY2[1])
console.log(cordY2[2])
console.log(cordY2[3])
console.log(cordY2[4])
console.log(cordY2[5])
console.log(strTest)
var cordYtest = parseInt(cordY2, 10);
console.log(cordYtest)
}
}
You just need to change the regex so that you replace everything except digits and the negative sign - rather than just whitespace. i.e.
change
var cordY2 = cordY.replace(/\s/g, '')
to
var cordY2 = parseInt(cordY.replace(/[^0-9-]/g, ''), 10);
So that the variable cordY2 contains the number you require.
Find below the code we have developed in java script to run in jmeter using JSR223 sampler(running as a java script). The same code worked on Jquery when developed but not posting the id while running in jmeter. the error thrown is "appid" is not defined. Could someone help debugging the issue looking at the code
vars.put("guid", "${__UUID}");
vars.put("appId", "ce547c40-acf9-11e6-80f5-76304dec7eb7");
var id=getAppInfo(appId, guid);
function getAppInfo(appId, guid)
{
var appInfo = null;
var appIdBytes = guidToBytes(appId);
var guidBytes = guidToBytes(guid);
var appInfoBytes = [];
for (var cnt = 0; cnt < appIdBytes.length; cnt++)
{
appInfoBytes[cnt] = appIdBytes[cnt] + guidBytes[cnt];
}
var appInfoGuidfromBytes = bytesToGuid(appInfoBytes);
return appInfoGuidfromBytes;
}
function bytesToGuid(guidBytes) {
var x = guidBytes;
var result = "";
var bytes = x.slice(0, 4).reverse().concat(x.slice(4, 6).reverse()).concat(x.slice(6, 8).reverse()).concat(x.slice(8));
var y = bytes.map(function (item) { return ('00' + item.toString(16)).substr(-2, 2) });
var byteArray = y;
for (var cnt = 0; cnt < byteArray.length; cnt++) {
if (cnt === 4 || cnt === 6 || cnt === 8 || cnt === 10)
result = result + "-" + byteArray[cnt];
else
result = result + byteArray[cnt];
}
return result;
}
function guidToBytes(guid) {
var bytes = [];
guid.split('-').map(function (number, index) {
var bytesInChar = index < 3 ? number.match(/.{1,2}/g).reverse() : number.match(/.{1,2}/g);
bytesInChar.map(function (byte) { bytes.push(parseInt(byte, 16)); });
});
return bytes;
}
// Create the Randon Number. It will call from NewGuid function.
function getRandomNumber() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
};
// Creating GUID eg. "cbe26df8-2b01-4377-9ae8-1d023ccd5171"
// getRandomNumber returns 4 digit Alphanumeric number and we are going to concatenating this with "-" symbol and third number starts with "-4" and substring the random number and concatenate the string and return.
function newGuid() {
return (getRandomNumber() + getRandomNumber() + "-" + getRandomNumber() + "-4" + getRandomNumber().substr(0, 3) + "-" + getRandomNumber() + "-" + getRandomNumber() + getRandomNumber() + getRandomNumber()).toLowerCase();
};
You shouldn't call JMeter's function inside JSR223 script.
Instead, add it to Parameters field as ${__UUID}
and then use it using args:
vars.put("guid", args[0]);
args - the parameters as a String array (split on whitespace)
I'm currently trying to write a JavaScript program which is able to recognize strings of similar elements. For example, suppose you had the ordered variables
var x1 = 1;
var x2 = 1;
var x3 = 0;
var x4 = 0;
var x5 = 1;
var x6 = 1;
var x7 = 1;
var x8 = 0;
var x9 = 1;
var x10 = 0;
I'm trying to produce a program which could tell you that these ordered variables contain one string of two 1's, one string of three 1's, and one string of one 1.
I thought I might be able to do this using an if statement, maybe something like
var i = 1;
var s = 0;
if(x_i == 1) {
var s = s ++;
var i = i++
}
elseif(x_i == 0) {
document.getElementById('string-length').innerHTML = s;
}
However, it is obviously not correct to write x_i to refer to each variable x1, x2, x3, ...
What should I do to make the program look at each variable in order and then consider the number of consecutive 1's in the list of ordered variables?
Thanks
You've said you're open to using a array. That looks like this:
var x = [
1,
1,
0,
0,
1,
1,
1,
0,
1,
0
];
Then you can loop through that array, keeping track of what you see:
var found; // Defaults to the value `undefined`
var count = 0;
x.forEach(function(entry) {
if (found === entry) {
++count;
} else {
if (count) {
console.log("Found " + count + " " + found + "s");
}
found = entry;
count = 1;
}
});
if (count) {
console.log("Found " + count + " " + found);
}
Array#forEach calls the function you give it once per entry, passing in the entry. We use that to compare to found and if it's a match, we increase count. If not (and it won't be the first time), we say what we found before (if anything) and then remember the new thing we've found.
The reason found won't be === entry on the first pass is that the default value of a variable is undefined, and undefined is not === either 0 or 1, because === is the "strict" equality operator, which means that the operands are only considered equal if they have the same type and value. undefined is not a number, so it doesn't have the same type.
Live Example:
var x = [
1,
1,
0,
0,
1,
1,
1,
0,
1,
0
];
var found; // Defaults to the value `undefined`
var count = 0;
x.forEach(function(entry) {
if (found === entry) {
++count;
} else {
if (count) {
snippet.log("Found " + count + " " + found);
}
found = entry;
count = 1;
}
});
if (count) {
snippet.log("Found " + count + " " + found + "s");
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
First off, I suck at remembering languages, so bear with me...this will be some ugly psudocode...
eval is going to be your friend.
http://www.w3schools.com/jsref/jsref_eval.asp
Use a for loop and an array that creates the list of values something like this
Array numbers = new Array[10]
for(i = 1, i<10, i++){
numbers [I]=eval("x"+ i).Value()
}
That gets your numbers in a list you can then work with.
You can now do a for loop like this
count = 0
countsArray[10]
for(I = 0, I < stuff.size, I++){
if(stuff[I] = 1)
count++
if(stuff[I] = 0){
countsArray.Add(count);
count=0;
}
}
//Print your counts or whatever here.
Dunno...you can get slick about all that and do it in one loop I think as well.
I'm currently implementing a substring search. From the algorithm, I get array of substrings occurence positions where each element is in the form of [startPos, endPos].
For example (in javascript array):
[[1,3], [8,10], [15,18]]
And the string to highlight is:
ACGATCGATCGGATCGAGCGATCGAGCGATCGAT
I want to highlight (in HTML using <b>) the original string, so it will highlight or bold the string from position 1 to 3, then 8 to 10, then 15 to 18, etc (0-indexed).
A<b>CGA</b>TCGA<b>TCG</b>GATC<b>GAGC</b>GATCGAGCGATCGAT
This is what I have tried (JavaScript):
function hilightAtPositions(text, posArray) {
var startPos, endPos;
var startTag = "<b>";
var endTag = "</b>";
var hilightedText = "";
for (var i = 0; i < posArray.length; i++) {
startPos = posArray[i][0];
endPos = posArray[i][1];
hilightedText = [text.slice(0, startPos), startTag, text.slice(startPos, endPos), endTag, text.slice(endPos)].join('');
}
return hilightedText;
}
But it highlights just a range from the posArray (and I know it is still incorrect yet). So, how can I highlight a string given multiple occurrences position?
Looking at this question, and following John3136's suggestion of going from tail to head, you could do:
String.prototype.splice = function( idx, rem, s ) {
return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};
function hilightAtPositions(text, posArray) {
var startPos, endPos;
posArray = posArray.sort(function(a,b){ return a[0] - b[0];});
for (var i = posArray.length-1; i >= 0; i--) {
startPos = posArray[i][0];
endPos = posArray[i][1];
text= text.splice(endPos, 0, "</b>");
text= text.splice(startPos, 0, "<b>");
}
return text;
}
Note that in your code, you are overwriting hilightedText with each iteration, losing your changes.
Try this:
var stringToHighlight = "ACGATCGATCGGATCGAGCGATCGAGCGATCGAT";
var highlightPositions = [[1,3], [8,10], [15,18]];
var lengthDelta = 0;
for (var highlight in highlightPositions) {
var start = highlightPositions[highlight][0] + lengthDelta;
var end = highlightPositions[highlight][1] + lengthDelta;
var first = stringToHighlight.substring(0, start);
var second = stringToHighlight.substring(start, end + 1);
var third = stringToHighlight.substring(end + 1);
stringToHighlight = first + "<b>" + second + "</b>" + third;
lengthDelta += ("<b></b>").length;
}
alert(stringToHighlight);
Demo: http://jsfiddle.net/kPkk3/
Assuming that you're trying to highlight search terms or something like that. Why not replace the term with the bolding?
example:
term: abc
var text = 'abcdefgabcqq';
var term = 'abc';
text.replace(term, '<b>' + term + '</b>');
This would allow you to avoid worrying about positions, assuming that you are trying to highlight a specific string.
Assuming your list of segments is ordered from lowest start to highest, try doing your array from last to first.
That way you are not changing parts of the string you haven't reached yet.
Just change the loop to:
for (var i = posArray.length-1; i >=0; i--) {
If you want to check for multiple string matches and highlight them, this code snippet works.
function highlightMatch(text, matchString) {
let textArr = text.split(' ');
let returnArr = [];
for(let i=0; i<textArr.length; i++) {
let subStrMatch = textArr[i].toLowerCase().indexOf(matchString.toLowerCase());
if(subStrMatch !== -1) {
let subStr = textArr[i].split('');
let subStrReturn = [];
for(let j=0 ;j<subStr.length; j++) {
if(j === subStrMatch) {
subStrReturn.push('<strong>' + subStr[j]);
} else if (j === subStrMatch + (matchString.length-1)){
subStrReturn.push(subStr[j] + '<strong>');
} else {
subStrReturn.push(subStr[j]);
}
}
returnArr.push(subStrReturn.join(''));
} else {
returnArr.push(textArr[i]);
}
}
return returnArr;
}
highlightMatch('Multi Test returns multiple results', 'multi');
=> (5) ['<strong>Multi<strong>', 'Test', 'returns', '<strong>multi<strong>ple', 'results']
This is my integer value
12232445
and i need to get like this.
12,232,445
Using prototype how to get this?
var number = 12232445,
value = number.toString(),
parts = new Array;
while (value.length) {
parts.unshift(value.substr(-3));
value = value.substr(0, value.length - 3);
}
number = parts.join(',');
alert(number); // 12,232,445
It might not be the cleanest solution, but it'll do:
function addCommas(n)
{
var str = String(n);
var result = '';
for(var i = 0; i < str.length; i++)
{
if((i - str.length) % 3 == 0)
result += ',';
result += str[i];
}
return result;
}
Here is the function I use, to format thousands separators and takes into account decimals if any:
function thousands(s) {
var rx = /(-?\d+)(\d{3})/,
intDec = (''+s)
.replace(new RegExp('\\' + $b.localisation.thousandSeparator,'g'), '')
.split('\\' + $b.user.localisation.decimalFormat),
intPart = intDec[0],
decPart = intDec[1] || '';
while (rx.test(intPart)) {
intPart = intPart.replace(rx,'$1'+$b.localisation.thousandSeparator+'$2');
}
return intPart + (decPart && $b.localisation.decimalFormat) + decPart;
}
thousands(1234.56) //--> 1,234.56
$b.localisation is a global variable used for the session.
$b.localisation.thousands can have the values , or . or a space.
And $b.localisation.decimalFormat can have the values , or . depending on the locale of the user