I'm working on a grid layout function. I'm about 1/2 way there and have hit a wall.
I am using a string and running a single RegExp function per box I'm placing in the grid to determine where it will fit (based on number of rows/columns it occupies). This works successfully. Demonstration:
function findSpace(columns, rows){
var totalColumns = 4;
var grid = "11002100020000200002";
//1 represents occupied space, 0 empty space, and 2 a new line
var reg = RegExp("(0{" + columns + "})(([0-2]{" + (totalColumns - columns + 1) + "})0{"+columns+"}){" + (rows-1) + "}");
var i = grid.search(reg);
return i.index;
}
Returns the index of the match, letting me know where in my grid this box will fall. See fiddle.
I fall short trying to replace the "0"s with "1"s. Doing grid.replace(reg, "1") of course replaces everything from the beginning of the match to the end with a single "1". I need to replace just the "0"s that will be occupied for row and column, each with a "1", and not any of the characters matched between.
This is an exercise in doing things differently. Yes, I could do this with an array data structure. What fun is that? I'm not looking for a "don't do it this way do it the way everyone else does" answer, I'm trying to determine the most efficient way to solve my scenario.
Thanks!
The String#replace method might be the ticket. If you pass a regular expression and a function as the second parameter, you can dynamically manipulate each match.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
Related
This pertains to any language that you think will work. Is there a way to change the look of a text input to replace every second space (space as in when the space bar is hit it makes a space) i need to a way almost like a counter that once it counts 2 spaces then it replaces that 2nd space to a letter or symbol. if someone could help me with this it would be amazing and the purpose is just to change the way the text looks in this way functionality does not matter as long as it reads like normal text. ( if it helps it would be every odd number of spaces gets changed.)
for example i want to be able to copy and paste something in like this> "i went down to the sea to pick up many sticks for my collection"
and have it return something like this
i%went down%to the%sea to%pick up%many sticks%for my%collection
the end goal is for the symbol to be a different color so it stands out from the text so if that would be possible that would be amazing.
I chose javascript, but there are multiple languages that you could choose and there are multiple ways to accomplish this. This is the train of thought that you should use when solving this problem:
Determine the characters that you want to replace
Determine the character that you want to replace it with
Since we don't want to replace every single one, what is the pattern/frequency that you want to replace found occurrences with.
For the 3rd question, you've said that you want to replace every other occurrence, so we need to keep track of the count of occurrences. And replace it when occurrence modulo 2 = 1. This says replace every odd occurrence.
I chose to use regex to find all the spaces in the sentence, have a counter n and increment the counter every time I find a space.
This leaves us with the following code:
const input = "i went down to the sea to pick up many sticks for my collection";
let n = 0;
const output = input.replace(/\s/g, (m, i, og) => {
return (n++ % 2) ? m : '%';
});
// output = "i%went down%to the%sea to%pick up%many sticks%for my%collection"
Also please take a look at String.prototype.replace() so you can learn about using regex, and to learn about what the function does. This will help you learn and solve similar problems by yourself in the future.
you can use a boolean variable to count odd and even spaces and string.prototyoe.replace with a callback function:
var str = 'i went down to the sea to pick up many sticks for my collection';
var odd = true;
str = str.replace(/\s/gi, (spaceChar)=>{
odd = !odd;
return !odd ? spaceChar : '%'; // this is what you wrote (every second)
// return odd ? spaceChar : '%'; // this is what your expected result shows (every second starting with the first occurence)
});
I have the following example url: #/reports/12/expense/11.
I need to get the id just after the reports -> 12. What I am asking here is the most suitable way to do this. I can search for reports in the url and get the content just after that ... but what if in some moment I decide to change the url, I will have to change my algorythm.
What do You think is the best way here. Some code examples will be also very helpfull.
It's hard to write code that is future-proof since it's hard to predict the crazy things we might do in the future!
However, if we assume that the id will always be the string of consecutive digits in the URL then you could simply look for that:
function getReportId(url) {
var match = url.match(/\d+/);
return (match) ? Number(match[0]) : null;
}
getReportId('#/reports/12/expense/11'); // => 12
getReportId('/some/new/url/report/12'); // => 12
You should use a regular expression to find the number inside the string. Passing the regular expression to the string's .match() method will return an array containing the matches based on the regular expression. In this case, the item of the returned array that you're interested in will be at the index of 1, assuming that the number will always be after reports/:
var text = "#/reports/12/expense/11";
var id = text.match(/reports\/(\d+)/);
alert(id[1]);
\d+ here means that you're looking for at least one number followed by zero to an infinite amount of numbers.
var text = "#/reports/12/expense/11";
var id = text.match("#/[a-zA-Z]*/([0-9]*)/[a-zA-Z]*/")
console.log(id[1])
Regex explanation:
#/ matches the characters #/ literally
[a-zA-Z]* - matches a word
/ matches the character / literally
1st Capturing group - ([0-9]*) - this matches a number.
[a-zA-Z]* - matches a word
/ matches the character / literally
Regular expressions can be tricky (add expensive). So usually if you can efficiently do the same thing without them you should. Looking at your URL format you would probably want to put at least a few constraints on it otherwise the problem will be very complex. For instance, you probably want to assume the value will always appear directly after the key so in your sample report=12 and expense=11, but report and expense could be switched (ex. expense/11/report/12) and you would get the same result.
I would just use string split:
var parts = url.split("/");
for(var i = 0; i < parts.length; i++) {
if(parts[i] === "report"){
this.reportValue = parts[i+1];
i+=2;
}
if(parts[i] === "expense"){
this.expenseValue = parts[i+1];
i+=2;
}
}
So this way your key/value parts can appear anywhere in the array
Note: you will also want to check that i+1 is in the range of the parts array. But that would just make this sample code ugly and it is pretty easy to add in. Depending on what values you are expecting (or not expecting) you might also want to check that values are numbers using isNaN
Pulling data with AJAX, into an array, everuthing there works fine, then I have this...
$.each(data, function (key, value){
var add = value[5]+value[6];
var sub = add.replace(" ","");
var link = 'http://'+sub+'.mydomain.com';
}
//OUTPUT: http://RR1 Box 22USHIGHWAY 67.NextHomeTown.com
This isn't working. It's not replacing any space characters.
Now, here's where it gets fun. This works on every other DB entry that is returned that has a space. Crazy, right?
Is there some type of character encoding that might be causing it not to recognize the space character that is used in this particular entry? The MySQL table has them entered as varchar, but at this point in the process, they're both just text strings right? So it shouldn't matter.
This will only replace the first spacebar it will match. Use this to replace all spacebars:
var sub = add.replace(/\s/g,"");
Since you report the desired behaviour with other tables, it's perhaps not relevant - but don't forget that in javascript, the string replace function only replaces the first instance of the searchString, unless you use a regular expression.
"red, red, red".replace(/ /g, "");
"red,red,red"
"red, red, red".replace(" ", "");
"red,red, red"
I need to count a group of regular expressions in a dynamically loaded <div> that I've loaded using the load() function. I also need to resize this <div> to the longest line of characters in it. Is there a way to achieve this? I've tried searching around and can't find anything, not even on SO. I should mention that the expression I am testing for is:
Sat Mar 12 12:45:38 PST 2011
Using this regex:
if ($('#result').text().match(/[A-Za-z]{3}\s[A-Za-z]{3}\s[0-9]{1,2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[A-Z]{3}\s[0-9]{4}/))
var str="The rain in SPAIN stays mainly in the plain";
var patt1=/ain/gi; //noticed the g. g will enable match of all occurance, and without it it'll only match the first occurance
console.log(str.match(patt1).length); //4 matched
JavaScript match regex function returns an array so you can basically do a length on that array and get the size of the matched elements. Make sure you are using the g in RegEx to search all occurance
Based on your RegEx you can do the following:
$('#result').text().match(/[A-Za-z]{3}\s[A-Za-z]{3}\s[0-9]{1,2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[A-Z]{3}\s[0-9]{4}/g).length //this should give you the total count of occurance
kjy112 gave you your answer. Like that answer clarified, this isn't really jQuery, but Javascript RegEx's (so maybe that was throwing off your search).
If that regex turns out to be slow-- which it might if you return many dates-- you can just count some nique component, such as just the years:
$('#result').text().match(/\d{4}/).length
Malfy,
3 ways to get the width of a string come to mind. I'll go over those first, then how to get the length of the longest. It looks like others have addressed the regex.
1) (fastest)
If only the text itself needs to be a certain width, not the div, then you can use white-space:nowrap to ensure the text remains the full width.
$('div.someClass').css('whiteSpace','nowrap');
2) (slowest)
If you need the pixel width of a string to set another div's width, one way to do that is to create an element containing that string and use the css property above. Example:
var yourString = 'your string';
// create a div containing your string
var $tempDiv = jQuery('<div style="visibility:hidden;position:absolute;white-space:nowrap">'+jQuery.trim(yourString)+'</div>').appendTo('body');
$newDiv = <your new div, however you're creating it>;
// set the width of the new div to the width of the temp div
$newDiv.width($tempDiv.width());
// and clean up;
$tempDiv.remove();
//repeat as necessary
3) (quite fast too)
Alternately, if you're sure you'll be using a monospace font (courier, consolas, etc). There's a much faster way. Save the width of a single character and multiplying it by the length of each new text string. That way you aren't writing a new element each time. For example:
var $tempDiv = $('<div style="visibility:hidden;margin:0;padding:0;border:0;">z</div>').appendTo('body');
//(any character will work. z is just for example);
var reusableCharacterWidth=$tempDiv.width();
$tempDiv.remove();
var firstString = your string';
// set the width of your first div
$newDiv.width(reusableCharacterWidth*firstString.length);
var nextString = 'your next string';
// set the width of your next div
$nextNewDiv.width(reusableCharacterWidth*nextString.length);
(note: you may want to use $.trim() on the strings just in case)
To get the longest string:
var longestLineLength,
yourText= 'your text here';
function getLongestLineLength(lines){
var oneLineLength,
longest=0,
linesArray = lines.split('\n');
for(var i=0,len=linesArray.length;i<len;i++){
oneLineLength=linesArray[i].length;
longest=oneLineLength>longest?oneLineLength:longest;
}
return longest;
}
longestLineLength = getLongestLineLength(yourText);
Cheers!
Adam
Ive got a really strange problem with some javascript code that ive written. I have set this code to execute on load. The idea of it is to remove a value from a text field if it is listed in another field. Here is the code:
var diseases = document.getElementById("AffectedBy").value;
var diseasearray = diseases.split("-");
alert("disease array size: " + diseasearray.length);
for (i=0;i<diseasearray.length;i++)
if (diseases.match("-" + diseasearray[i]))
{
diseasearray[i] = "-" + diseasearray[i];
alert(diseasearray[i]);
document.getElementById("DiseaseNotSelected").value=document.getElementById("DiseaseNotSelected").value.replace(diseasearray[i],"")
}
This code above gives an array size of 3 (1 blank, and 2 values) but when I display the values in the alert it only shows 2 values(1 blank, and 1 value)
This piece of code:
var foods = document.getElementById("FoodFor").value;
var foodarray = foods.split("-");
alert("food array size: " + foodarray.length);
for (i=0;i<foodarray.length;i++)
if (foods.match("-" + foodarray[i]))
{
foodarray[i] = "-" + foodarray[i];
alert(foodarray[i]);
document.getElementById("FoodNotSelected").value=document.getElementById("FoodNotSelected").value.replace(foodarray[i],"")
}
This code above gives an array size of 3 (1 blank, and 2 values) and when I display the values in the alert it only shows 3 values(1 blank, and 2 value).
Can anyone see a reason why the first code block only shows 2 items in the array as I cant see why and its really bugging me now.
the first one is running a match against a string starting with '-'.
I don't have your actual values, but let's say that the value of #AffectedBy is "test1-test2-test3".
the first alert will be 3, because the diseasearray will have three components (test1, test2, test3)
you then run through a loop (0, 1, 2).
The first one will fail, as there is no "-test1" in the string, but the other two will succeed, as there are "-test2" and "-test3" substrings.
As I said in my comment above: beware that whatever you pass into match will get turned into a regular expression. If that contains some special character, it might not match where you would expect it to (or vice versa).
The string White Spot (Ich) will be turned into the regex /White Spot (Ich)/; which does not match White Spot (Ich) but does match White Spot Ich, since the parentheses are grouping operators in a regex.
Change the regular expression test
diseases.match("-" + diseasearray[i])
into the plain string comparison
diseases.indexOf("-" + diseasearray[i]) !== -1
and you should be set.
(I think. :-)
First, for the length you need to do for example foodarray.length -1.
How many items do you have in your array (suppose to have)? We need more explanation