-4

I have cities and countires list in a json file. For a given string, I need to check the city name and country name is present or not. If present I have to capitalize the word. what is the best way to acheive this in node JS

Please consider json from this link. https://raw.githubusercontent.com/russ666/all-countries-and-cities-json/master/countries.json

my input is "united states to play davis cup in bratislava"

output should be "United States to play davis cup in Bratislava"

Hint: First letter of city and country name should be capital.

I am expecting code something like this

var myString="united states to play davis cup in bratislava";
var data=myjson;
var i=0;
myString=myString.split("");
for(i=0;i<myString.length;i++){
var output="";
//help this line
var check=myString[i].match(data)
if(check){
output+=myString[i].charAt(0).toUpperCase() + myString[i].slice(1);
}
else{
output+=myString[i]}
}
Ramesh arr
  • 19
  • 6

2 Answers2

0

It all starts from function start() at the bottom. For displaying purpose i've used a small dataset but you can require the data from the json file by using const data = require('data.json'). I've tested for large dataset also, works like a charm. Hope it helps.

const data = {
    "United States":[
    "Washington","Bratislava","Hard","Going"],  
    "Afghanistan": [
    "Herat",
    "Kabul",
    "Kandahar",
    "Molah",
    "Rana",
    "Shar",
    "Sharif",
    "Wazir Akbar Khan"
]};
Array.prototype.myJoin = function(start,end){
    if(!start) start = 0;
    if(!end) end = this.length - 1;
    end++;
    return this.slice(start,end);
};


const getCityData = async (country) => {
    return country;
}

const changeFormat = async () => {
    try {
        let countries = Object.keys(data).map( (country, index) => {
            return country;
        })
        let citiesData = [];
        await countries.map( (country, index) => {
            citiesData = citiesData.concat(data[country]);
        })
        return countries.concat(citiesData);
    } catch (err) {
        return err;
    }
}
const checkSentence = (text, text_original, number, modified_data) => {
    return new Promise((resolve, reject)=>{
        try {
            if( !text || !text.length ){
                throw new Error('empty text');
            }
            // console.log('started ' + number);
            // console.log('number ' + number +' started')
            let upperCase = [];
            const number_const = number;
            let temp1 = new Array(text.length);
            temp1.fill(2);
            temp1.map( (v, i) => {
                // let temp = text;
                let temp = [...text_original, ...[]];
                // console.log('i' + i);
                // console.log('number' + number);
                
                if(i + number <= text.length ) {
                    // console.log('inside 1st if');
                    temp = temp.slice(i, i + number)
                    // console.log(text + ' 1');
                    temp = temp.join(' ')
                    // console.log(text + ' 2');                    
                    temp = temp.toLowerCase();
                    // console.log(text + ' 3');                    
                    if(modified_data.indexOf(temp) != -1){                        
                        upperCase.push({ start: i, end: i + number - 1 })
                    }
                }
            })
            
            let toBeChanged = [];
            if(upperCase.length){
             upperCase.map( (v, i) => {
                 // console.log(v);
                 let arr = range( v.start, v.end )
                 toBeChanged = toBeChanged.concat(arr);
             })
            }
            // console.log('ended number' + number);
            // console.log(toBeChanged);
            return resolve(toBeChanged);
        } catch (err) {
            return reject(err);
            // console.error(err);
            // return false;
        }      
    })
}

const range = (start, end) => {
    // console.log(start);
    // console.log(end);
    return Array(end - start + 1).fill().map((_, idx) => start + idx)
}

const start = async() => {
    try {
        excludeWords.map( (word, index) => {
            excludeWords[index] = excludeWords[index].toLowerCase();
        });
        
        let modified_data_1 = await changeFormat(); 
        let maximum = 1;
        modified_data = modified_data_1.map( (v, i) => {
            if(v.split(' ').length > maximum){
                maximum = v.split(' ').length
            }
            if(excludeWords.indexOf(v.toLowerCase()) == -1) {
                return v.toLowerCase();
            }
        });
        text = text.split(' ');
        if(maximum > text.length){
            maximum = text.length;
        }
        // console.log(maximum);
        let temp = new Array(maximum);
        temp.fill(2);
        let answer = await temp.map( (v, i) => {
            let tempArray = [...text, ...[]];
            let tempArray1 = [...text, ...[]];
            return checkSentence(tempArray, tempArray1, (maximum - i), modified_data);
        })
        return Promise.all(answer).then( (results) => {
            let merged = [].concat.apply([], results);
            // console.log('merged');
            merged = new Set(merged);
            merged = [...merged];
            // console.log(merged);
            merged.map((v, i) => {
                if(v == undefined || v == null){
                    return;
                }
                let temp1 = text[v].split('');
                temp1[0] = temp1[0].toUpperCase();
                text[v] = temp1.join('');
            })
            // console.log(text.join(' '));
            return text.join(' ');
        }).catch((err)=>{
            console.log(err);
        })  
    } catch (err) {
        // console.error('here ERROR');
        console.error(err);
        return false;
    }
}

let excludeWords = ['Hard', 'Going'];
let text = 'united states to davis cup hard wazir Akbar Khan in bratislava';

( async () => {
    let answer = await start();
    console.log(answer);
})();
Atishay Jain
  • 1,425
  • 12
  • 22
  • Hi @Atishay, Thanks for your help. Please see my answer Can you help on this new case? – Ramesh arr Sep 26 '18 at 04:34
  • In that case it's better if you delete it from the JSON itself otherwise I'll need to hardcode it which is not a good option. – Atishay Jain Sep 26 '18 at 05:12
  • Yea, but I have to manipulate this to 10 lakhs set of strings. so it not better idea to remove cities. Else I have to find a json file with major cities in world only – Ramesh arr Sep 26 '18 at 05:19
  • So do one thing make an array something like `const removeWords = ['hard', 'world']` and filter the modified array. I'll update my code code in another 1 hour. – Atishay Jain Sep 26 '18 at 05:31
  • Thanks it is fine. but I don't know excluded words for 10 lakhs record of strings. Any way will try to find a json file with major cities alone. Do you have idea of handling 10 lakhs records of strings in node js – Ramesh arr Sep 26 '18 at 06:41
  • yes, store it in a json file, not in a database as it'll be faster. Make sure the json file is readonly for security purposes. use `fs` module to read the file. – Atishay Jain Sep 26 '18 at 06:46
  • Thanks bro, the data is in excel and have to write the output back in excel. I'll handle it. – Ramesh arr Sep 26 '18 at 06:51
  • Happy to help :) – Atishay Jain Sep 26 '18 at 06:52
  • Will that handle the town in Paraguay named "Doctor Pedro P. Peña"? – Rick James Dec 24 '18 at 05:22
0

Hi I have done in simple way it is also working. My problem is in the string the word "davis" also present as a city in json. How to not capitalize that word. For ex: "Hard", "Going" these words also have city name. but these words not be considered as city in my program.

Case 1:

Input: taiwan hit hard by sars outbreak.

Output should be: Taiwan hit hard by sars outbreak.

My output: Taiwan hit Hard by sars outbreak.

Please install capitalize npm and use data.json folder in your root folder to execute below code

var myData=require("./data");
var countriesArray=Object.keys(myData.data);
var citiesArray=Object.values(myData.data);
var capitalize=require('capitalize');
var citiesFlatten = [].concat.apply([], citiesArray);
var countryCities=countriesArray.concat(citiesFlatten);

var str = 'russia ponders space tourism deal';
var pattern = new RegExp("\\b("+countryCities.join("|")+")\\b","ig");
var matchArray=str.match(pattern);
if(!!matchArray){
    matchArray.forEach(function(item) {
        str=str.replace(item,capitalize.words(item));
    });
    console.log( str.replace(/^\w/, c => c.toUpperCase()));
}
Ramesh arr
  • 19
  • 6