Checking if a string isn't a space in Javascript - javascript

So I have a program that counts the words in a document that is loaded into an iFrame, all of the newline characters are replaced by a space, then the string is split by spaces, I then want to add them to a map as the key and set their value to 1 if they're not in the map or not a space, this is where I'm having the problem because it's still counting each space in the string , I feel like I'm being really stupid and missing something obvious...
var innerDoc = document.getElementById("pageinframe");
var innerDocContent = innerDoc.contentDocument.body.innerHTML;
var split = strip(innerDocContent).replace(/(\r\n|\n|\r)/gm, " ").split(" ");
var obj = new Map();
for (var x = 0; x < split.length; x++) {
console.dir(typeof split[x]);
if(!obj.has(split[x]) && (split[x] != " ")) {
obj.set(split[x], 1);
}
else if (split[x] != " ") {
obj.set(split[x], obj.get(split[x])+1);
}
}
function strip(str) {
var tmp = document.createElement("DIV");
tmp.innerHTML = str;
return tmp.textContent || tmp.innerText || "";
}

There are something, icant understand. When you split(' '). the array not contains ' ', only words!!!, https://www.w3schools.com/jsref/jsref_split.asp. Son Why need to testif is white space. Then i think, it could be in:
.replace(/(\r\n|\n|\r)/gm, " ")

The split array contained "" not " " like I originally thought. Like I said I was missing something really obvious, just needed to see what was in the array.

var innerDoc = document.getElementById("pageinframe");
var innerDocContent = innerDoc.contentDocument.body.innerHTML;
var split = strip(innerDocContent).replace(/(\r\n|\n|\r)/gm, " ").split(" ");
var obj = new Map();
for (var x = 0; x < split.length; x++) {
// Removing NaN for string
if(split[x].charCodeAt(0))
{
if(!obj.has(split[x]) && (split[x] != " ")) {
obj.set(split[x], 1);
}
else if (split[x] != " ") {
obj.set(split[x], obj.get(split[x])+1);
}
}
}
function strip(str) {
var tmp = document.createElement("DIV");
tmp.innerHTML = str;
return tmp.textContent || tmp.innerText || "";
}
console.log(obj);

Related

Why is this constructor (using "new Function") breaking?

I'm brand new to JS and am trying to build a template function (assignment in a MOOC) that basically returns a function that returns the rendered template based on an input string and delimiter.
Anyway, this is the code that I have so far and I have no idea why it is breaking.. I've really tried everything that I can think of!
var template = function(stringToParse, options) {
// find out if custom delimiters are being used
if (typeof options != 'undefined') {
var openDelim = options.open;
var closeDelim = options.close;
} else {
var openDelim = '*(';
var closeDelim = ')*';
}
// get the length of the closing delim for parsing later
var delimCharLen = closeDelim.length;
// helper function
function parseOutFiller(_array) {
// get an array of the indices of each closing delim in the string
var closingDelims = [];
for (i=0; i < _array.length; i++) {
closingDelims.push(_array[i].indexOf(closeDelim));
}
// remove the filler text leading up to the closing dim in each substring
for (i = 0; i < _array.length; i++) {
if (closingDelims[i] > 0) {
_array[i] = _array[i].slice(closingDelims[i] + delimCharLen)
}
}
return _array
}
// split array, get the closing indices, and parse out the filler text
var splitArray = stringToParse.split(openDelim);
var parsedString = parseOutFiller(splitArray);
return new Function("var locParsedString = [" + parsedString + "];\
var inputCopy = [];\
for (i=0; i < arguments.length-1; i++) {\
inputCopy.push(arguments[i])\
}\
var templateString = '';\
for (i=0; i < inputCopy.length; i++) {\
templateString += locParsedString[i];\
templateString += inputCopy[i];\
}\
templateString += locParsedString[locParsedString.length-1];\
nRepeat = arguments[arguments.length-1];\
for (i=0; i < nRepeat; i++) {\
console.log(templateString);\
}"
)
}
Then when I run it...
var string = "Is <<! thing !>> healthy to <<! action !>>?";
var logResult = template(string, {open: '<<!', close: '!>>'});
logResult('this', 'eat', 3)
/*
Which should print:
"Is this healthy to eat?"
"Is this healthy to eat?"
"Is this healthy to eat?"
*/
Thanks in advance!
Instead of using new Function(), just use return function () { }.
That way, there is no need to create locParserString inside the function. You can use parsedString directly:
var template = function(stringToParse, options) {
// find out if custom delimiters are being used
if (typeof options != 'undefined') {
var openDelim = options.open;
var closeDelim = options.close;
} else {
var openDelim = '*(';
var closeDelim = ')*';
}
// get the length of the closing delim for parsing later
var delimCharLen = closeDelim.length;
// helper function
function parseOutFiller(_array) {
// get an array of the indices of each closing delim in the string
var closingDelims = [];
for (i=0; i < _array.length; i++) {
closingDelims.push(_array[i].indexOf(closeDelim));
}
// remove the filler text leading up to the closing dim in each substring
for (i = 0; i < _array.length; i++) {
if (closingDelims[i] > 0) {
_array[i] = _array[i].slice(closingDelims[i] + delimCharLen)
}
}
return _array
}
// split array, get the closing indices, and parse out the filler text
var splitArray = stringToParse.split(openDelim);
var parsedString = parseOutFiller(splitArray);
return function () {
var inputCopy = [];
for (i=0; i < arguments.length-1; i++) {
inputCopy.push(arguments[i])
}
var templateString = '';
for (i=0; i < inputCopy.length; i++) {
templateString += parsedString[i];
templateString += inputCopy[i];
}
templateString += parsedString[parsedString.length-1];
nRepeat = arguments[arguments.length-1];
for (i=0; i < nRepeat; i++) {
console.log(templateString);
}
};
}

Convert JSON in comma separated string with nested array

I know there are a lot of examples out there, but still I can't get it working. I have a JSON like this:
{"domiciles":[{"country":"AF"},{"country":"AX"},{"country":"AL"}],"investor":[{"type":"ii"},{"type":"pi"}]}
stored in sessionStorage.getItem("profile");
How can I convert in two comma seperated strings? Like ...
AF,AX,AL
ii,pi
Failed attempts:
var dataResidence = sessionStorage.getItem("profile");
var resultResidence = dataResidence.map(function(val) {
return val.country;
}).join(',');
console.log(resultResidence);
Or:
var newString = "";
for(var i=0; i< dataResidence.domiciles.length;i++){
newString += userDefinedSeries.country[i];
newString += ",";
}
console.log(newString);
You need to parse the string you get from the sessionStorage, then you can map and join:
var profile = '{"domiciles":[{"country":"AF"},{"country":"AX"},{"country":"AL"}],"investor":[{"type":"ii"},{"type":"pi"}]}'; // sessionStorage.getItem("profile");
var dataResidence = JSON.parse(profile);
function mapAndJoin(arr, key) {
return arr.map(function(o) {
return o[key];
}).join();
}
var domiciles = mapAndJoin(dataResidence.domiciles, 'country');
var investor = mapAndJoin(dataResidence.investor, 'type');
console.log(domiciles);
console.log(investor);
One way of doing it
var obj={"domiciles":[{"country":"AF"},{"country":"AX"},{"country":"AL"}],"investor":[{"type":"ii"},{"type":"pi"}]};
console.log(JSON.stringify(obj));
var countries = obj.domiciles;
var str = '';
for(i=0;i<countries.length;i++){
if(i != countries.length - 1)
str+= countries[i].country+",";
else
str += countries[i].country;
}
console.log(str);
var type = obj.investor;
var str1 = '';
for(i=0;i<type.length;i++){
if(i != type.length - 1)
str1 += type[i].type+",";
else
str1 += type[i].type;
}
console.log(str1);

Replace last letters in array of strings Javascript

I need to do as follows:
I've got an array of strings containing last names. Some of them ends with letter 'i'.
manLastNames = ["testowski","bucz","idzikowski","gosz"];
I need to make a function which will iterate over this array of strings and if there is an element ending with 'i', I need to replace this 'i' for 'a', otherwise just leave string as it is.
At the end I want to have another array where all last 'i's are replaced with 'a's.
womanLastNames = ["testowska","bucz","idzikowska","gosz"];
This is what I have now, but Im pretty sure that it start being crap at some point
var rep = function() {
var manLastNames = ["testowski","bucz","idzkowski","gosz"];
var womanLastNames = new Array(4);
for (var i=0; i<manLastNames.length; i++) {
var lastName = manLastNames[i];
if (lastName.substr(lastName.length - 1, 1) == 'i') {
lastName = lastName.substr(0, lastName.length - 1) + 'a';
}
}
for (var i=0; i<womanLastNames.length; i++) {
womanLastNames[i] = lastName[i];
}
console.log(womanLastNames);
}
rep();
Try the code:
var manNames = ["testowski","bucz","idzkowski","gosz"];
var womanNames = manNames.map(function(name) {
return name.endsWith("i") ? name.slice(0, -1) + "a" : name;
});
console.log(womanNames)
If your interpreter supports ES6, the following is equivalent:
names.map((name)=>name.endsWith("i") ? name.slice(0, -1) + "a" : name)
Here is solution
var rep = function() {
var manLastNames = ["testowski","bucz","idzkowski","gosz"];
var womanLastNames =[];
for (var i=0; i<manLastNames.length; i++) {
var lastName = manLastNames[i];
if (lastName.charAt(lastName.length - 1) == 'i') {
lastName = lastName.substr(0, lastName.length - 1) + 'a';
}
womanLastNames.push(lastName);
}
console.log(womanLastNames);
}
rep();
Another solution is to use .map method like this, using a callback function:
var manLastNames = ["testowski","bucz","idzikowski","gosz"];
function mapNames(item){
return item[item.length-1]=='i' ? item.substr(0, item.length-1) + "a" : item;
}
console.log(manLastNames.map(mapNames));
Depending on how efficient you need to be, you can use regular expressions to do both tasks:
var new_name = name.replace(/i$/, 'a');
will replace the last "i" in a string with "a" if it exists
var new_name = name.replace(/i/g, 'a');
will replace all "i"s in a string with "a".
var names = ["testowski", "bucz", "idzkowski", "gosz"];
console.log("original", names);
var last_i_replaced = names.map(function(name) {
return name.replace(/i$/, 'a');
});
console.log("last 'i' replaced", last_i_replaced);
var all_i_replaced = names.map(function(name) {
return name.replace(/i/g, 'a');
});
console.log("all 'i's replaced", all_i_replaced);
This should work:
var rep = function() {
var manLastNames = ["testowski","bucz","idzkowski","gosz"];
var womanLastNames = manLastNames;
for(var i=0; i<manLastNames.length;i++){
if(manLastNames[i].charAt(manLastNames[i].length-1)=='i'){
womanLastNames[i]=manLastNames[i].substr(0,womanLastNames[i].length-1)+'a';
}
}
console.log(womanLastNames);
}
rep();
Here is another solution
var manLastNames = ["testowski","bucz","idzkowski","gosz"];
var womanLastNames = []
manLastNames.forEach(x => {
if (x.charAt(x.length-1) === "i") womanLastNames.push(x.slice(0,-1).concat("a"));
else womanLastNames.push(x);
});
console.log(womanLastNames);

How to join a string in javascript based on a regex or if string starts with some value?

for instance I have this string:
013227004871996 300234060903250 013227003498171 013227003493834 300234010640390
013227003512963 300234061401690 013227004865956 013226009142122 013227008391574
300234061405690 013227003400573 300234061404700 013227003501479 013227003394495
013227004876284 300234061349230 013227004876284 013227004862011
and what I want to happen is that to separate the entry if it encounters 01322, so for instance in the example it will have array[0] = 013227004871996 300234060903250, array[1] = 013227003498171,
array[2] = 013227003493834
so basically I want to split it if the next entry starts with "013227".
This seems to work. Im matching everything that starts and is followed by 013227. Then I'm matching the last segment with .+
str.match(/013227.+?(?=013227)|.+/g)
Or even better:
str.split(/(?=013227)/)
var numbersStr = "013227004871996 300234060903250 013227003498171 013227003493834 300234010640390 013227003512963 300234061401690 013227004865956 013226009142122 013227008391574 300234061405690 013227003400573 300234061404700 013227003501479 013227003394495 013227004876284 300234061349230 013227004876284 013227004862011";
var pattern = new RegExp('01322[\\d]+');
var numbersArr = numbersStr.split(' ');
var numbersArrLength = numbersArr.length - 1;
for (var i = numbersArrLength; i >= 0; i--) {
if (!pattern.test(numbersArr[i])) {
numbersArr.splice(i, 1);
}
}
var separator = '01322';
"013227004871996 300234060903250 013227003498171 013227003493834 300234010640390"
.split(separator)
.filter(function(item){
return item;
}).map(function(item){
return separator + item;
})
var s = "013227004871996 300234060903250 013227003498171 013227003493834 300234010640390 "
+ "013227003512963 300234061401690 013227004865956 013226009142122 013227008391574 "
+ "300234061405690 013227003400573 300234061404700 013227003501479 013227003394495 "
+ "013227004876284 300234061349230 013227004876284 013227004862011";
var sp = s.split(" ");
var res = new Array();
var count=0;
sp.forEach(function(a) {
if(a.search("01322") === 0) {
if(res[count] === undefined) {
res[count] = a;
} else {
++count;
res[count] = a;
}
} else {
if(res[count] === undefined) {
res[count] = a;
} else {
res[count]+=" "+a;
}
}
});
console.log(res);
[ '013227004871996 300234060903250',
'013227003498171',
'013227003493834 300234010640390',
'013227003512963 300234061401690',
'013227004865956',
'013226009142122',
'013227008391574 300234061405690',
'013227003400573 300234061404700',
'013227003501479',
'013227003394495',
'013227004876284 300234061349230',
'013227004876284',
'013227004862011' ]
try this
function niceslice( string, delimiter ){
var result = string.split(delimiter);
for(var i = 1; i < result.length; i++){
result[i] = delimiter + result[i];
}
return result;
}
take note that this will not eliminate spaces in your example (but should be easily built in)
example usage
var str = 'anton albert andrew';
var output = niceslice( str, 'a' );
console.log( output ); // returns ['', 'anton ', 'albert ', 'andrew']
or in your case
var str = '013227004871996 300234060903250 013227003498171 013227003493834 300234010640390 013227003512963 300234061401690 013227004865956 013226009142122 013227008391574 300234061405690 013227003400573 300234061404700 013227003501479 013227003394495 013227004876284 300234061349230 013227004876284 013227004862011';
var output = niceslice( str, '013227' );

How to replace all capture groups if it is generated dynamically?

Consider the following code:
function Matcher(source, search) {
var opts = search.split('');
for (var i = 0; i < opts.length; i++) {
opts[i] = '(' + opts[i] + ')';
}
opts = opts.join('.*');
var regexp = new RegExp(opts, 'gi');
source = source.replace(regexp, function () {
console.log(arguments);
return arguments[1];
});
return source;
}
You call the function passing the source as the first parameter and what you need to match as the second one.
What i need is to replace all capture groups with a bold tag around the coincidence.
As an example, consider the following:
var patt = /m([a-z0-9\-_]*?)r([a-z0-9\-_]*?)i([a-z0-9\-_]*?)e([a-z0-9\-_]*\.[a-z]+)/gi;
var newFileName = fileName.replace(patt, "<strong>m</strong>$1<strong>r</strong>$2<strong>i</strong>$3<strong>e</strong>$4");
This code is an answer from Terry on my previous question but the problem here is that you need to know exactly what you want to replace, and i need it dynamically.
Any thoughts?
It seems like you're creating the pattern the wrong way round. Instead of building a(.*?)b(.*?)c, you create (a).*(b).*(c) - with the capturing groups around the parts you already know. Better:
function wrapEachLetter(source, search, tag) {
var opts = search.split('');
tag = tag || "strong";
return source.replace(new RegExp(opts.join("(.*?)"), 'gi'), function () {
var str = '<'+tag+'>'+opts[0]+'</'+tag+'>';
for (var i=1; i<opts.length; i++)
str += arguments[i] + '<'+tag+'>'+opts[i]+'</'+tag+'>';
return str;
});
}
Example:
> wrapEachLetter("testExampleString", "tex", "b")
"<b>t<b><b>e<b>stE<b>x<b>ampleString"
Capture the delimiters too and then process only even subgroups, leaving odd ones as is:
s = "ABC---DEF---HIJ"
re = /(\w+)(.*?)(\w+)(.*?)(\w+)/
s.replace(re, function() {
return [].slice.call(arguments, 1, -2).map(function(a, n) {
return n & 1 ? a : "<strong>" + a + "</strong>"
}).join("")
})
> "<strong>ABC</strong>---<strong>DEF</strong>---<strong>HIJ</strong>"
However, if your goal is to highlight only individual characters, it's much simpler this way:
str = "myfile.js"
letters = "mis"
re = new RegExp("[" + letters + "]", "gi")
str.replace(re, "<b>$&</b>")
> "<b>m</b>yf<b>i</b>le.j<b>s</b>"
or, without regular expressions:
str = "myfile.js"
letters = "mis"
str.split("").map(function(s) {
return letters.indexOf(s) >= 0 ? "<b>" + s + "</b>" : s
}).join("")
> "<b>m</b>yf<b>i</b>le.j<b>s</b>"
var input = "aBcDeFgHiJk",
match = 'be';
str = '',
reg = '',
i = 0;
function escapeRegExp(c) {
return c.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
// /(.*)(b)(.*)(e)(.*)/gi
// '$1<b>$2</b>$3<b>$4</b>$5'
for (var c in match) {
if (i == 0) {
str += '$' + ++i;
reg += '(.*)';
i++;
}
str += '<b>$' + i++ + '</b>$' + i++;
reg += '(' + escapeRegExp(match[c]) + ')(.*)';
}
alert(input.replace(new RegExp(reg, 'ig'), str)); // <- a<b>B</b>cD<b>e</b>FgHiJk

Categories

Resources