Example Company 1,company ltd 2,company, Inc.,company Nine nine, ltd,company ew So here is example of the string, I want to split it like that it consider Company 1 as one company and company, Inc. as one, but here got situation in company, Inc. it condidering 2 companies while this logic. how can I resolve this? Lke with such strings company, Inc. I want to consider it one element only
const company = company.split(",");
Here the string can be anything, this is just example for the string, but it can be any name. So I am looking for generic logic which works for any string, having same structure of string.
Note $ ==(,) represents as separation point, kept to get clarity that from that point I need to separate the string
Object:
Example 1
{
_id: 5de4debcccea611e4d14d4d5
companies: One Bros. Inc. & Might Bros. Dist. Corp.$Pages, Inc.$Google Inc. Search$Aphabet Inc. tech.
}
Example 2
{
_id: 5de4debccc333611e4d14d4f5
companies: Google Comp. Inc.$Google Comp. Inc. Estd.$Tree, Ltd.$Tree, Ltd.
}
First I split on 'ompany' rather than 'company', because you have one instance of 'Company' with a capital C -- see the output of the first console log within a comment below.
Then I put things back together using reduce -- map is not the right choice here, as I need an array that is one fewer than the size of the fragments I generated. Then though since I need an array that corresponds to the number of strings we want to return, which is one fewer than the number of fragments, the first thing I do inside my reduce is ensure I do not look beyond the end of the array.
Then I split each fragment and pop off the last element, which just puts either "C" or "c" back together with "ompany". Then I replace any trailing ',c' from the next fragment with an empty string, and add the result to the company. Finally I add the entire result to the array I'm generating with reduce. See comment results at bottom. Also here it is on repl.it: https://repl.it/#dexygen/splitOnCompanyStringLiteral
This is a fairly concise way to do this but again if you can do anything to improve your data, you won't have to use such unnecessarily complicated code.
const companiesStr = "Company 1,company ltd 2,company, Inc.,company Nine nine, ltd,company ew";
const companySuffixFragments = companiesStr.split("ompany");
console.log(companySuffixFragments);
/*
[ 'C', ' 1,c', ' ltd 2,c', ', Inc.,c', ' Nine nine, ltd,c', ' ew' ]
*/
const companiesArr = companySuffixFragments.reduce((companies, fragment, index, origArr) => {
if (index < companySuffixFragments.length - 1) {
let company = fragment.split(',').pop() + 'ompany'
company = company + origArr[index + 1].replace(/,c$/, '');
companies.push(company);
}
return companies
}, []);
console.log(companiesArr);
/*
[ 'Company 1',
'company ltd 2',
'company, Inc.',
'company Nine nine, ltd',
'company ew' ]
*/
First change , with any other symbol. I am using & here and then split string with ,
var str= 'Company 1,company ltd 2,company, Inc.,company Nine nine, ltd,company ew';
str = str.replace(', Inc.','& Inc.');
/*str = str.replace(', ltd','& ltd');*/
console.log(str.split(',').map((e)=>{return e.replace('&',',').trim()}));
try with the below solution.
var str = ["company 1","company ltd 2","company", "Inc.","company Nine nine", "ltd","company ews"];
var str2 =str.toString()
var str3 = str2.split("company")
function myFunction(item, index,arr){if(item !=""){let var2 = item.replace(/,/g," ");var2 = "Company"+var2;arr[index]=var2;} }
str3.forEach(myFunction)
OUtput:
str3
(6) ["", "Company 1 ", "Company ltd 2 ", "Company Inc. ", "Company Nine nine ltd ", "Company ews"]
And remove the first element of the array.
As has been commented I'd try to get a more clean String so that you don't have to write "strange" code to get what you need.
If you can't do that right now this code should solve your problem:
let string = 'Company 1,company ltd 2,company, Inc.,company Nine nine, ltd,company
ew';
let array = string.split(',');
const filterFnc = (array) => {
let newArr = [],
i = 0;
for(i = 0; i < array.length; i++) {
if(array[i].toLowerCase().indexOf('company') !== -1) {
newArr.push(array[i]);
} else {
newArr.splice(newArr.length - 1, 1, `${array[i - 1]}, ${array[i]}`);
}
}
return newArr;
};
let filteredArray = filterFnc(array);
Related
The following code gets the first word from my page title, compares it to the values of an array and outputs me a final value :
var fulltitle = "Deep Blue Shoes";
var arr = fulltitle.split(' ').slice(0, 1);
var title = arr && arr.length ? arr[0] : "";
//test variables
testarray = ["blue", "top", "110", "in stock", "deep blue", "down", "111", "in stock"]
//function
function testfunction(array, variable) {
var varindex = array.indexOf(variable.toLowerCase())
return array[varindex + 2]
}
//calling the function
var finalvalue = testfunction(testarray, title);
console.log( finalvalue )
In this case, if my title is Deep Blue shoes, the system cuts the title too early and try to compare the value 'deep' with the values into the array. But the value deep doesn't exist.
I'm trying to find a solution for this and similiar problems that may occur, since my variables can be like 'blue', 'deep blue', 'deep blue sky'. We work with exact matches only.
How would you fix this ?
See also https://jsfiddle.net/Francesco82/hg10a3wy/
You could use a String (or RegEx) comparison?
But in the first example this matches with both "blue" as well as "deep blue" (and in the second "acquacalda" as well as "acqua").
What logic should we use in those cases? If it matches with more than one, choose the one with the most words if one has more words than the others (i.e., in that case, choose "deep blue") and if the matches are the same number of words choose the longer of the two words? i.e. In the second case choose "acquacalda" over "acqua"? (in general, always choosing the more specific answer)
See below and https://jsfiddle.net/alexander_L/gx83mrtL/3/
findPage("Deep Blue Shoes");
findPage("Acquacalda");
function findPage(fulltitle){
//test variables
const testarray = ["blue", "top", "110", "in stock", "deep blue", "down", "111", "in stock", "acqua", "top", "112", "in stock", "acquacalda", "down", "113", "in stock"]
const altMatches = testarray.reduce((aggArr, item) => {
if (fulltitle.toLowerCase().includes(item)){
console.log('we have a match with ' + item);
aggArr.push(item);
}
return aggArr;
}, []);
//then we can choose the "largest" match:
const finalMatch = altMatches.reduce((aggMatch, item) => {
if (aggMatch == null || (aggMatch.split(' ').length < item.split(' ').length) || (aggMatch.length < item.length)){
return item;
}
return aggMatch;
}, null);
console.log('the final match is ' + finalMatch);
const finalPage = testarray.indexOf(finalMatch) + 2;
console.log('the final match page number is ' + testarray[finalPage]);
}
OUTPUT:
"we have a match with blue"
"we have a match with deep blue"
"the final match is deep blue"
"the final match page number is 111"
"we have a match with acqua"
"we have a match with acquacalda"
"the final match is acquacalda"
"the final match page number is 113"
I was able to fix the problem with a trick just by modifing this code at the very beginning
var fulltitle = (document.title);
var arr = fulltitle.split(':').slice(0, 1);
Since the part of title we need is always before the ':' , in this way I'm able to get the right result without making advanced comparisons.
How can i remove all instances of :smile: style emjois from a string using javascript? Here is an example below I got in JSON with :point_right: in it. I'd love to remove all of them from a string.
[ { service_name: 'Instagram',
title: 'Instagram: “:point_right: Real people, making real products from real plants, using their actual hands to put them in boxes that show up on your doorstep.…”',
text: '36 Likes, 2 Comments - “:point_right: Real people, making real products',
ts: '1523497358.000299' }
Just use String.prototype.replace() with a regular expression:
const input = 'Instagram: “:point_right: Real people, making real products from real plants, using their actual hands to put them in boxes that show up on your doorstep.…”';
const output = input.replace(/:\w+:/g, '');
console.log(output);
Assuming the emojis are all one word, between :s:
const obj = {
service_name: 'Instagram',
title: 'Instagram: “:point_right: Real people, making real products from real plants, using their actual hands to put them in boxes that show up on your doorstep.…”',
text: '36 Likes, 2 Comments - “:point_right: Real people, making real products',
ts: '1523497358.000299'
}
obj.title = obj.title.replace(/:[^ ]+:/g, '');
obj.text = obj.text.replace(/:[^ ]+:/g, '');
console.log(obj);
From this answer Replacing values in JSON object you could do this :
var json=[ { service_name: 'Instagram',
title: 'Instagram: “:point_right: Real people, making real products from real plants, using their actual hands to put them in boxes that show up on your doorstep.…”',
text: '36 Likes, 2 Comments - “:point_right: Real people, making real products',
ts: '1523497358.000299' }];
var rep = JSON.stringify(json).replace(/(“)(:[^:]+:)/g, '$1');
var New = JSON.parse(rep);
console.log(New);
Try this :
// JSON Object
var jsonObj = [{
"service_name": "Instagram",
"title": "Instagram: “:point_right: Real people, making real products from real plants, using their actual hands to put them in boxes that show up on your doorstep.…”",
"text": "36 Likes, 2 Comments - “:point_right: Real people, making real products",
"ts": "1523497358.000299"
}];
// Replace :point_right: with blank string.
jsonObj.map(obj => {
obj.title = obj.title.replace(":point_right: ", "");
obj.text = obj.text.replace(":point_right: ", "");
return obj;
});
// Output
console.log(jsonObj);
I'm loading json file from database with two fields words and grade. Each word is graded for example true has 1 while lie has -1. Then i take input from text filed and i need to grade it based on grades from JSON file and then calculate score by summarizing the grades, but i just can't seem to find the way to do that. Words that are not in file are not being calculated.
I tried string.search match but it's to complicated and in the end i couldn't get result the way i wanted. I tried array searches same thing. I searched for on line solution, but no one has done anything similar so i can't copy it.
JSON
[
{"word":"true","grade":1},
{"word":"hate","grade":-1},
{"word":"dog","grade":0.8},
{"word":"cat","grade":-0.8}
]
String
"Dogs are wonderful but i prefer cats, cats, i can not lie although dog is a true friend".
The first thing I'd do is turn your JSON data into a map which can easily be searched - key would be the word, and value the grade:
var json = [
{"word":"true","grade":1},
{"word":"hate","grade":-1},
{"word":"dog","grade":0.8},
{"word":"cat","grade":-0.8}
];
var map = json.reduce(function(p,c){
p.set(c.word.toLowerCase(),c.grade);
return p;
}, new Map());
console.log(...map);
Then, its just a case of splitting your string, whilst also calculating the total score - again reduce can be used
var json = [
{"word":"true","grade":1},
{"word":"hate","grade":-1},
{"word":"dog","grade":0.8},
{"word":"cat","grade":-0.8}
];
var map = json.reduce(function(p,c){
p.set(c.word.toLowerCase(),c.grade);
return p;
}, new Map());
var input = "Dogs are wonderful but i prefer cats cats i can not lie although dog is a true friend";
var score = input.split(' ').reduce(function(p,c){
var wordScore = map.get(c.toLowerCase()) || 0;
return p + wordScore;
},0);
console.log(score);
Note that I have manually removed punctuation in the above input - I'll leave that as an exercise for you.
Also note that "cats" != "cat" so some of your words wont be found!
Let's first think of the algorithm. Two options:
Search and count the input string as many times as number of words in your JSON, or
Check each word in your input string against the JSON contents.
Since the JSON length is known and (I presume) shorter than the possible input string, I would tend to prefer option 2.
Now, after selecting option 2, you need to split the input string into words and create an array containing one word each entry of the array.
You can achieve this using the mystring.split(" ") method. This, of course, does not take into account punctuations, but you can handle this using the same method.
Now, you can add to each entry in your JSON a field to count the number of appearances of each entry in the JSON within the string.
Finally, you sum the product of the counters and the grade.
console.log((function(rules, str) {
var sum = 0;
Array.prototype.forEach.call(rules, function(rule) {
var match = str.match(rule.regexp);
match && (sum += str.match(rule.regexp).length * rule.grade);
console.log([rule.regexp, match&&match.length, rule.grade, match&&match.length * rule.grade, sum]);
});
return sum;
})([{
"regexp": /true/g,
"grade": 1
}, {
"regexp": /hate/g,
"grade": -1
}, {
"regexp": /dog/g,
"grade": 0.8
}, {
"regexp": /cat/g,
"grade": -0.8
}], "Dogs are wonderful but i prefer cats, cats, i can not lie although dog is a true friend"));
i use regexp rather than string, u can use string and convert to regex at run time, hope this would help
I have the following array of strings. The names are locations, and each location has 4 integers "attached" to it.
Using regex (in nodeJS, with javascript), I am trying to extract the name of the location, and the last (4th) of the integers for each location.
[ ' UNICENTRO CALI 1131908 296780 133622 968750',
' PASTO 2 1044057 212780 133004 964281',
' CALIMA 1397254 311214 173761 1259801',
' PALMIRA2 922857 272954 103978 753881',
' PEREIRA CRA 6 1188885 157589 165004 1196300',
' DE LA CUESTA-BUCARAMANGA 219916 49526 27261 197651' ]
for example, for the first location I would need to fish out "UNICENTRO CALI" and "968750".
To do this, I've tried:
myArray[i].split(" ")
This separates the name of the location from the four integers, but this will turn into an inefficient mess.
Any chance somebody can do it elegantly with a regular expression?
If you aren't specifically looking for a Regex to parse your entire data, here's one way to do it easily:
var a = [ 'Total C.O. UNICENTRO CALI 1,131,908 296,780 133,622 968,750',
'Total C.O. PLAZA CAICEDO 988,721 272,182 114,641 831,180',
'Total C.O. COSMOCENTRO 692,679 159,488 85,309 618,500',
'Total C.O. PASTO 2 1,044,057 212,780 133,004 964,281'];
var b = [];
a.forEach(function(item){
var splitItem = item.split(/\s\s+/),
len = splitItem.length;
b.push({"name":splitItem[1], "value":splitItem[len-1]});
});
console.log(b);
I used the data from your Regex101 link to demonstrate in this jsFiddle.
This will capture all your columns:
/'\s+(.*\S)?\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)'/
capture group 1 = location
capture group 2 = num 1
capture group 3 = num 2
capture group 4 = num 3
capture group 5 = num 4
var str = "' UNICENTRO CALI 1131908 296780 133622 968750'";
var arr = /'\s+(.*\S)?\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)'/.exec(str);
> console.log(arr)
[Log] Array (6)
0"' UNICENTRO CALI 1131908 296780 133622 968750'"
1"UNICENTRO CALI"
2"1131908"
3"296780"
4"133622"
5"968750"
Array Prototype
Your data changed, use this:
/'(.*\S)\s+([\d,]+)\s+([\d,]+)\s+([\d,]+)\s+([\d,]+)'/
https://regex101.com/r/jJ6xM7/2
Give this a try:
/^'\s+(\w+ +\w*)( +\d+){3} +(\d+)'/
Where $1 (group 1) is your location and $3 (group 3) is the last set of integers on each line.
As I mentioned, your data from the original post changed. Use ergonaut's recommended expression:
/'(.*\S)\s+([\d,]+)\s+([\d,]+)\s+([\d,]+)\s+([\d,]+)'/
Ok folks I have bombed around for a few days trying to find a good solution for this one.
What I have is two possible address formats.
28 Main St Somecity, NY 12345-6789
or
Main St Somecity, Ny 12345-6789
What I need to do Is split both strings down into an array structured as such
address[0] = HousNumber
address[1] = Street
address[2] = City
address[3] = State
address[4] = ZipCode
My major problem is how to account for the lack of a house number. with out having the whole array shift the data up one.
address[0] = Street
address[1] = City
address[2] = State
address[3] = ZipCode
[Edit]
For those that are wondering this is what i am doing atm . (cleaner version)
place = response.Placemark[0];
point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
FCmap.setCenter(point,12);
var a = place.address.split(',');
var e = a[2].split(" ");
var x = a[0].split(" ");
var hn = x.filter(function(item,index){
return index == 0;
});
var st = x.filter(function(item,index){
return index != 0;
});
var street = '';
st.each(function(item,index){street += item + ' ';});
results[0] = new Hash({
FullAddie: place.address,
HouseNum: hn[0],
Dir: '',
Street: street,
City: a[1],
State: e[1],
ZipCode: e[2],
GPoint: new GMarker(point),
Lat: place.Point.coordinates[1],
Lng: place.Point.coordinates[0]
});
// End Address Splitting
Reverse the string, do the split and then reverse each item.
Update: From the snippet you posted, it seems to me that you get the address from a Google GClientGeocoder Placemark. If that is correct, why are you getting the unstructured address (Placemark.address) instead of the structured one (Placemark.AddressDetails)? This would make your life easier, as you would have to try and parse only the ThoroughfareName, which is the street level part of the address, instead of having to parse everything else as well.
function get_address (addr_str) {
var m = /^(\d*)\s*([-\s\w.]+\s(?:St|Rd|Ave)\.?)\s+([-\s\w\.]+),\s*(\w+)\s+([-\d]+)$/i.exec(s);
var retval = m.slice(1);
if (!retval[0]) retval = retval.slice(1);
return retval;
}
Assume all streets ends with St, Rd or Ave.
var address = /[0-9]/.match(string.charAt(0))
? string.split(" ") : [ " "
].concat(string.split(" "));
This is not particularly robust, but it accounts for the two enumerated cases and is concise at only one line.
I've got a similar problem I'm trying to solve. It seems that if you look for the first space to the right of the house number, you can separate the house number from the street name.
Here in Boston you can have a house number that includes a letter! In addition, I've seen house numbers that include "1/2". Luckily, the 1/2 is preceded by a hyphen, so there aren't any embedded spaces in the house number. I don't know if that's a standard or if I'm just getting lucky.