how to parse a .RC file using Javascript - javascript

I am trying to parse the data from a .RC (resource definition file) to JSON using js with simple fs.readFile function, however I am getting SyntaxError: Invalid or unexpected token. At the moment I've found no other solution to parse this type of file, pls provide me with inputs to do so. Below is .RC example.
#include "shapes.h"
ShapesCursor CURSOR SHAPES.CUR
ShapesIcon ICON SHAPES.ICO
ShapesMenu MENU
{
POPUP "&Shape"
{
MENUITEM "&Clear", ID_CLEAR
MENUITEM "&Rectangle", ID_RECT
}
}
I found a package in node called, 'Jison' which is an API for creating parsers in JavaScript similar to 'PegJS', however I couldn't figure out the grammer that needs to be written for my file type also if it would support the file type. The parsed structure could look similar to,
{
"directive": [
"include",
"shapes.h"
],
"data": [
{
"name": "ShapesCursor",
"values": [
"CURSOR",
"SHAPES.CUR"
],
"children": []
},
{
"name": "ShapesIcon",
"values": [
"CURSOR",
"SHAPES.ICO"
],
"children": []
},
{
"name": "POPUP",
"values": [
"&Shape"
],
"children": [
{
"name": "MENUITEM",
"values": [
"&Clear",
"ID_CLEAR"
],
"children": []
},
{
"name": "MENUITEM",
"values": [
"&Rectangle",
"ID_RECT"
],
"children": []
}
]
}
]
}

Below grammar can be used for parsing Resource Description files to a JSON.
{
var word_Obj = {};
var word_alnum_Obj = {};
var word_alnumsp_Obj = {};
var dir_Obj = {};
var valStateDec_Obj = {};
var stateName_Obj = {};
var valStateVal_Obj = {};
var word_Count = 0;
var word_alnum_Count = 0;
var word_alnumsp_Count = 0;
var dir_Count = -1;
var valStateDec_Count = 0;
var stateName_Count = -1;
var valStateVal_Count = -1;
var begin_Count = -1;
var end_Count = -1;
var child_Count = -1;
var children_Count = -1;
var flag = 0;
}
Expected = dir:directive * nl * states:state nl* Ending:EOL {if (begin_Count === end_Count) { return { Parsed_RC: { Directive_Obj: dir, States_Obj: states, ENDING: Ending } } } else { return "Incorrect .RC file" } }
directive = "#" d: word space* v:word_alnumsp nl+ { dir_Count++; dir_Obj = { ['Directive_' + dir_Count]: { "Dir": d, "_text": v } }; return dir_Obj;}
state = (valState looping)*
looping = (loopStart loopEnd*)*
loopStart = beg child: valState + { begin_Count++; children_Count++; child_Count++; return {['loopStart_' + begin_Count]: begin_Count, ['child_' + children_Count]: child } }
loopEnd = end {end_Count++; child_Count--; return { ['loopEnd_' + end_Count]: end_Count }; }
valState = stateName(valStateVal) * nl +
//valStateDec = space+ decState_val:word_alnumsp {valStateDec_Count++; valStateDec_Obj = {['ValStateDec_Obj'+valStateDec_Count]:decState_val}; return valStateDec_Obj;}
stateName = space * state_name:word_alnumsp {if (state_name === 'BEGIN') { begin_Count++; children_Count++; child_Count++; return { ['loopStart_' + begin_Count]: begin_Count } } if (state_name === 'END') { end_Count++; child_Count--; return { ['loopEnd_' + end_Count]: end_Count }; } if (child_Count < 0) { flag = 1; } stateName_Count++; stateName_Obj = { ['StateName_Obj' + stateName_Count]: state_name }; return stateName_Obj; }
valStateVal = space + valState_val:(word_alnumsp comma?)* { valStateVal_Count++; valStateVal_Obj = { ['_attributes_Obj' + valStateVal_Count]: valState_val }; return valStateVal_Obj}
word = wo:letter + { return wo.join("") }
word_alnum = al:alnum + { return al.join("") }
word_alnumsp = alsp:alnumsp + { return alsp.join("") }
beg = space * ([{]) space* nl +
end = space * ([}]) space* nl +
comma = space * [,] space* { return ","}
letter = [a - zA - Z]
alnum = [a - zA - Z0 - 9]
alnumsp = [a - zA - Z0 - 9"'&._()\\|+:]
space = " "
nl = '\n' {valStateVal_Count = -1; return "NL"}
EOL = !. {return "EOF"}

Related

Split JSON value to obtain new JSON with news properties

This is my first post today because I'm exhausted.
I try since few days to make something that looks simple but not for me...
I've this JSON :
[
{
"GpName":"AAAAAA",
"Contacts":"US;Toto;\nESI;James;james#mail.com "
},
{
"GpName":"BBBBBB",
"Contacts":"ESI;Sebastien;sebastien#mail.com\nUS;Ahmid;\nESI;Stephane ;Stephane#mail.com"
},
{
"GpName":"CCCCCC",
"Contacts":"ESI;Marc;Marc#mail.com\nUS;Olivier;olivier#mail.com\nUS;Jean;jean#mail.com"
}
]
I try to use the split array function, I don't have the result expected.
How could I obtain :
[
{
"GpName":"AAAAAA",
"Contacts":["Zone":"US",
"User":"Toto"
"Mail": " "],
["Zone":"ESI",
"User":"James",
"Mail":"james#gmail.com "]
},
{
"GpName":"BBBBBB",
"Contacts":["Zone":"ESI",
"User":"Sebastien"
"Mail": "sebastien#mail.com"],
["Zone":"US",
"User":"Ahmid ",
"Mail":" "]
["Zone":"ESI",
"User":"Stephane",
"Mail":"Stephane#mail.com"]
},
{
"GpName":"CCCCCC",
"Contacts":["Zone":"ESI",
"User":"Marc"
"Mail": "Marc#mail.com"],
["Zone":"US",
"User":"Olivier",
"Mail":" "]
["Zone":"US",
"User":"Jean",
"Mail":"Jean#mail.com"]
}
]
As you can see, sometimes I've email, sometime not.
Any help would be very grateful
use Array.split Split a string into substrings and Array.map to generate an array.
let input = [{ "GpName": "AAAAAA", "Contacts": "US;Toto;\nESI;James;james#mail.com " }, { "GpName": "BBBBBB", "Contacts": "ESI;Sebastien;sebastien#mail.com\nUS;Ahmid;\nESI;Stephane ;Stephane#mail.com" }, { "GpName": "CCCCCC", "Contacts": "ESI; Marc; Marc#mail.com\nUS; Olivier; olivier#mail.com\nUS; Jean; jean#mail.com" }]
let result = input.map(({ GpName, Contacts }) => ({
GpName,
Contacts: Contacts.split("\n").map(line => {
let [Zone, User, Mail] = line.split(";");
return { Zone, User, Mail }
})
}));
console.log(result)
What I tried on my side
var EsiEmailList = [];
var EsiEmailListJSON = [];
var myJSON = JSON.parse(BgManagerInfoList);
for (key in myJSON) {
gpInfo = myJSON[key];
var gpName= gpInfo.GpName;
var gpContact = gpInfo.Contacts;
EsiEmailListJSON.push(gpContact);
}
EsiEmailList=JSON.stringify(EsiEmailListJSON);
EsiEmailListSplit = EsiEmailListJSON/split("\n");
for (data in EsiEmailListSplit){
contactInfo = EsiEmailListJSON[data];
System.log ("contactInfo: " + contactInfo);
}
The result is something like this :
**ContactInfo**: US;Toto;
ESI;James;james#mail.com
**ContactInfo**: ESI;Sebastien;sebastien#mail.com
US;Ahmid;
ESI;Stephane;Stephane#mail.com
**ContactInfo**:ESI;Marc;Marc#mail.com
US;Olivier;olivier#mail.com
US;Jean;jean#mail.com
same issue :
Error in (Workflow:TEst / map function (item1)#37) TypeError: Cannot find function map in object
I tested the polyfill but it's not working
Here the code
if (!Array.prototype.map) {
Array.prototype.map = function(callback/*, thisArg*/) {
var T, A, k;
if (this == null) {
throw new TypeError('this is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = arguments[1];
}
A = new Array(len);
k = 0;
while (k < len) {
var kValue, mappedValue;
if (k in O) {
kValue = O[k];
mappedValue = callback.call(T, kValue, k, O);
A[k] = mappedValue;
}
k++;
}
return A;
};
}
var input = [{ "GpName": "AAAAAA", "Contacts":
"US;Toto;\nESI;James;james#mail.com " }, { "GpName": "BBBBBB", "Contacts":
"ESI;Sebastien;sebastien#mail.com\nUS;Ahmid;\nESI;Stephane ;Stephane#mail.com"
}, { "GpName": "CCCCCC", "Contacts": "ESI; Marc; Marc#mail.com\nUS; Olivier;
olivier#mail.com\nUS; Jean; jean#mail.com" }];
var result = input.map(function (_a) {
var GpName = _a.GpName, Contacts = _a.Contacts;
return ({
GpName: GpName,
Contacts: Contacts.split("\n").map(function (line) {
var _a = line.split(";"), Zone = _a[0], User = _a[1], Mail = _a[2];
return { Zone: Zone, User: User, Mail: Mail };
})
});
});
Can I Maybe use the for each instead of map, something like this :
var inputJSON = JSON.parse(BgManagerInfoList);
for each(a in inputJSON ){
var GpName = a.GpName;
var Contacts = a.Contacts;
//System.log ("GpName: " + GpName);
//System.log ("Contacts: " + Contacts);
for each(b in Contacts){
b = line.split(";");
var Zone = b[0];
var User = b[1];
var Mail = b[2];
System.log ("Zone:" + Zone + ", User: " + User + ", Mail: " + Mail );
}
}
I've a value for GpName and Contacts but the for each is not working for Contacts
I found the solution of my problem :
var input = JSON.parse(BgManagerInfoList);
for each(a in input){
var GpName = a.GpName ;
var Contacts = a.Contacts;
//System.log ("GpName: " + GpName);
contactSplit = Contacts.split('\n');
System.log ("Contacts: " + Contacts);
for each (a in contactSplit){
var ContactOnly = a.split(";");
//System.log ("ContactsSplit: " + ContactsSplit);
var Zone = ContactOnly[0];
var User = ContactOnly[1];
var Mail = ContactOnly[2];
System.log ("Zone:" + Zone + ", User: " + User + ", Mail: " + Mail );
}
}
I made a first split of each lines, and for each line I made another split on the ";".
I got the expected result. Tks a lot for your suggestion, they helped me to understand of map is working and adapt my code to get the result.
I've to push the result in a table and work with.

Javascript Recursion with helper function

I have this chunk of code and I want to print this out.
a
|->b
|->c
|->e
It works when I use
let spaceStr = " ".repeat(level) + "|->";
but not when I use the helper function getSpace.
It only prints the following:
a
|->b
I cannot figure out why. Can someone explain to me?
const obj =
{ name: 'a', children:
[ { name: 'b', children: [] }
, { name: 'c', children:
[ { name: 'e', children: [] }
]
}
]
}
function getSpace(level){
var str = '';
for (i=0; i < level; i++){
str += ' ';
}
str += '|->';
return str
}
function getPath(obj, level) {
let result = [];
let resultString = '';
let spaceStr = " ".repeat(level) + "|->";
// let spaceStr = getSpace(level);
if (obj.children.length === 0) {
return spaceStr+obj.name;
} else {
if (level === 0) {
result.push(obj.name);
} else {
result.push(spaceStr + obj.name);
}
for (i=0;i<obj.children.length;i++){
result.push(getPath(obj.children[i], level+1));
}
}
return result;
}
function printPath(result){
for (i=0;i<result.length;i++){
console.log(result[i]);
}
return
}
printPath(getPath(obj,0).flat());
By using i=0 in your loops, you're not scoping the variable i correctly to the loop. Instead, it will bubble up to the closest instance of that variable name (until it hits the global scope). Consider using let i = 0 in your loops to properly scope the variable. See the following functioning code:
const obj = {
"name": "a",
"children": [{
"name": "b",
"children": []
},
{
"name": "c",
"children": [{
"name": "e",
"children": []
}]
}
]
}
function getSpace(level){
var str = '';
for (let i = 0; i < level; i++){
str += ' ';
}
str += '|->';
return str
}
function getPath(obj, level) {
let result = [];
let resultString = '';
//let spaceStr = " ".repeat(level) + "|->";
let spaceStr = getSpace(level);
if (obj.children.length === 0) {
return spaceStr+obj.name;
} else {
if (level === 0) {
result.push(obj.name);
} else {
result.push(spaceStr + obj.name);
}
for (let i = 0;i<obj.children.length;i++){
result.push(getPath(obj.children[i], level+1));
}
}
return result;
}
function printPath(result){
for (let i = 0;i<result.length;i++){
console.log(result[i]);
}
return
}
printPath(getPath(obj,0).flat());

Esprima get function and variable declarations

I want to get all function and variable declarations made in a Javascript code.
I use esprima and I wonder if there is script that I can use for my goal?
For example we have this code:
var myVar1;
var myVar2;
function myTestFunction(funcVar1, funcVar2) {
var myVar3;
}
What I except:
Array with variables
["myVar1", "myVar2"]
And an array with functions:
[{"name": "myTestFuncttion", "params":["funcVar1", "funcVar2"], "variables": ["myVar3"]}]
Any ideas how to achieve this?
Complete solution with fiddle:
Here is some JavaScript code for a test-run:
var hello = 41;
function aaaaa(p1, p2, p3){
var a1 = 7, a2 = 8;
var a3 = 9;
function bbbbb(q1, q2){
var b1 = 10, b2 = 11;
return 12;
}
var a4 = 99;
function ccccc(r1, r2, r3){
var c1 = 13;
var c2 = 14;
var c3 = 15, c4 = 16;
return 17;
}
var a5 = 88, a6 = 77;
function ddddd(s1){
return s1 === 18
? function (x){ return x+1; }
: function (y){ return 22; }
}
return p1 + a3 <= 42 ? 55 : ccc(p1, 0, 0);
}
var world = 42;
function xxxxx(x){
var z=0;
return 0;
}
I'm assuming that this is the desired output:
{
"vars": ["hello", "world" ],
"funcs": [
{
"name": "aaaaa",
"params": ["p1", "p2", "p3"],
"variables": ["a1","a2","a3","a4","a5","a6"]
},
{
"name": "bbbbb",
"params": ["q1","q2"],
"variables": ["b1","b2"]
},
{
"name": "ccccc",
"params": ["r1","r2","r3"],
"variables": ["c1","c2","c3","c4"]
},
{
"name": "ddddd",
"params": ["s1"],
"variables": []
},
{
"name": "xxxxx",
"params": ["x"],
"variables": ["z"]
}
]
}
The lists are flat and the anonymous functions within ddddd are being ignored (they are FunctionExpressions not FunctionDeclarations). Guessing that this is how you want it.
Here is the code - probably / hopefully easy to understand without further explanation:
function findDeclarations(code){
var ast = esprima.parse(code);
var funcDecls = [];
var globalVarDecls = [];
var funcStack = [];
function visitEachAstNode(root, enter, leave){
function visit(node){
function isSubNode(key){
var child = node[key];
if (child===null) return false;
var ty = typeof child;
if (ty!=='object') return false;
if (child.constructor===Array) return ( key!=='range' );
if (key==='loc') return false;
if ('type' in child){
if (child.type in esprima.Syntax) return true;
debugger; throw new Error('unexpected');
} else { return false; }
}
enter(node);
var keys = Object.keys(node);
var subNodeKeys = keys.filter(isSubNode);
for (var i=0; i<subNodeKeys.length; i++){
var key = subNodeKeys[i];
visit(node[key]);
}
leave(node);
}
visit(root);
}
function myEnter(node){
if (node.type==='FunctionDeclaration') {
var current = {
name : node.id.name,
params : node.params.map(function(p){return p.name;}),
variables : []
}
funcDecls.push(current);
funcStack.push(current);
}
if (node.type==='VariableDeclaration'){
var foundVarNames = node.declarations.map(function(d){ return d.id.name; });
if (funcStack.length===0){
globalVarDecls = globalVarDecls.concat(foundVarNames);
} else {
var onTopOfStack = funcStack[funcStack.length-1];
onTopOfStack.variables = onTopOfStack.variables.concat(foundVarNames);
}
}
}
function myLeave(node){
if (node.type==='FunctionDeclaration') {
funcStack.pop();
}
}
visitEachAstNode(ast, myEnter, myLeave);
return {
vars : globalVarDecls,
funcs : funcDecls
};
}
for testing, you can type
JSON.stringify(
findDeclarations(
'var hello=41;\n' +
aaaaa.toString() +
'var world=42;\n' +
xxxxx.toString()
),
null, 4
)
You can also use the estraverse package, it's available on github. Then, essentially, the function visitEachAstNode should be replaced by estraverse.traverse, and otherwise you can leave the code unchanged.
fiddle

Apparently assignment to proprierty of object does not work in javascript

Firs of all, I am newbie with Javascript and I think it is from about two hours that I am trying to understand this issue.
I have some objects (nested to one other object) where one property (called years) have this value: "1972-1974", for example. The value may change, but what remains the same is the presence of -. Object that have this property (year) with the value - need to be replicated, changing only year. If the value is "1972-1974" I want three object with value 1972, 1973 and 1974 in the year property (other property does not change).
Example of data structure.
{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [
{
"type": "Feature",
"properties": {
"years": "1972-1974",
}
},
This is my attempt to solve my requiriment:
function formatYears(data) {
data.forEach(
function(d, index) {
if(typeof d.properties.years === "string" && d.properties.years.includes("-")) {
var temp = d.properties.years.split("-");
var count = temp[temp.length - 1] - temp[0];
d.properties.years = parseInt(temp[0]);
for(var i = 0; i < count; i++) {
var newData = jQuery.extend({}, d);
newData.properties.years = parseInt(temp[0]) + i + 1;
data.push(newData);
}
}
}
)
}
I call this function with
formatYears(json.features);
where json store all data previusly loaded.
I do not know why but all new objects have as years property 1974, in our example.
I tried to debug it and newData.properties.years take the right value (1973 and then 1974), but newData after data.push(newData) does not hold 1973 and 1974, but always 1974.
UPDATE:
Add link to json.
UPDATE 2:
Solved.
function formatYears(data) {
data.forEach(
function(d, index) {
if(typeof d.properties.years === "string" && d.properties.years.includes("-")) {
var temp = d.properties.years.split("-");
var count = temp[temp.length - 1] - temp[0];
d.properties.years = parseInt(temp[0]);
for(var i = 0; i < count; i++) {
var newData = jQuery.extend(true, {}, d);
newData.properties.years = parseInt(temp[0]) + i + 1;
data.push(newData);
}
}
}
)
}
Why?
Simple for loop:
function formatYears(features) {
features.forEach(function(feature){
var fromto = feature.properties.years.split('-');
var years = [];
for (var y = +fromto[0]; y <= fromto[1]; ++y)
years.push(y);
feature.properties.years = years;
return years;
});
}
var f = [
{
"type": "Feature",
"properties": {
"years": "1972-1974",
}
},
{
"type": "Feature",
"properties": {
"years": "1975-1978",
}
}];
function formatYears(features) {
features.forEach(function(feature){
var fromto = feature.properties.years.split('-');
var years = [];
for (var y = +fromto[0]; y <= fromto[1]; ++y)
years.push(y);
feature.properties.years = years;
});
}
formatYears(f)
console.log(f.map(f => f.properties.years))
I have made some changes to your js code
function formatYears(data) {
var out = [];
data.forEach(
function(d, index) {
if(typeof d.properties.years === "string" && d.properties.years.includes("-")) {
var temp = d.properties.years.split("-");
var count = (parseInt(temp[1],10) - parseInt(temp[0],10)) + 1;
//d.properties.years = parseInt(temp[0]);
for(var i = 0; i < count; i++) {
var newData = jQuery.extend(true, {}, d);
newData.properties.years = parseInt(temp[0], 10) + i;
console.log(newData);
out.push(newData);
}
}
}
)
console.log(out);
}
and when I am calling this with a data like this
var data = {
"features": [
{
"type": "Feature",
"properties": {
"years": "1972-1974",
}
},
{
"type": "Feature",
"properties": {
"years": "2007-2008",
}
},
{
"type": "Feature",
"properties": {
"years": "2010-2011",
}
}
]
};
its working fine.
Solved.
function formatYears(data) {
data.forEach(
function(d, index) {
if(typeof d.properties.years === "string" && d.properties.years.includes("-")) {
var temp = d.properties.years.split("-");
var count = temp[temp.length - 1] - temp[0];
d.properties.years = parseInt(temp[0]);
for(var i = 0; i < count; i++) {
var newData = jQuery.extend(true, {}, d);
newData.properties.years = parseInt(temp[0]) + i + 1;
data.push(newData);
}
}
}
)
}

Group or rearrange array elements based on a condition - javascript

I have an array called 'country' which looks like:
country=[
{
"name": "china",
"id": "country:china"
}, {
"name": "city1",
"id": "country:country1>city1"
}, {
"name": "city2",
"id": "country:country1>city2"
}, {
"name": "city3",
"id": "country:country1>city3"
}, {
"name": "korea",
"id": "country:korea"
}, {
"name": "australia",
"id": "country:australia"
}
]
I am looking at rearranging/grouping the above array as:
countryResult = [ china, country1(city1, city2, city3), korea, australia]
I have written the following code but this does not give me the desired result:
$scope.countryInfo = function(itemData){
var countryResult = [];
for(var i=0; i<itemData.length; i++){
var countryItem = itemData[i];
if(countryItem.id.indexOf('>') > -1){ //Found city
var itemId = countryItem.id.substr(0, countryItem.id.indexOf('>'));
for(var j=0; j<$scope.countryData.length; j++){
if($scope.countryData[j].id == itemId){
var _parentChild = $scope.countryData[j].name + "( " + countryItem.name + " ) ";
countryResult.push(_parentChild);
}
}
}
else{
countryResult.push(countryItem.name);
}
}
return countryResult;
}
The result is coming up like this - [ china, country1(city1), country1(city2), country1(city3)), korea, australia]
Please let me know how to achieve the expected array result.
EDIT: I am just looking at simplifying the array [ china, country1(city1), country1(city2), country1(city3)), korea, australia] to [ china, country1(city1, city2, city3), korea, australia]
I've used reduce with an initial object with a keys property to capture the positions of the elements:
function sorter(countty) {
var obj = country.reduce(function (p, c, i) {
var key, id = c.id.split(/[:>]/);
if (id.length === 3) {
key = id[1];
if (!p[key]) {
p[key] = [];
p.keys.push(key);
}
p[key].push(id[2]);
} else {
p.keys.push(c.name);
}
return p;
}, { keys: [] });
return obj.keys.map(function (el) {
return obj[el] ? el + '(' + obj[el].join(', ') + ')' : el;
});
}
sorter(country);
DEMO
You can use a temporary object and then map the object's properties to the wanted array.
var country = [{ "name": "china", "id": "country:china" }, { "name": "city1", "id": "country:country1>city1" }, { "name": "city2", "id": "country:country1>city2" }, { "name": "city3", "id": "country:country1>city3" }, { "name": "korea", "id": "country:korea" }, { "name": "australia", "id": "country:australia" }],
temp = {},
result;
country.forEach(function (a) {
var b = a.id.split(/\:|\>/g);
temp[b[1]] = temp[b[1]] || [];
if (b[2]) {
temp[b[1]].push(b[2]);
}
});
result = Object.keys(temp).map(function (k) {
if (temp[k].length) {
return k + '(' + temp[k].join(', ') + ')';
}
return k;
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
I wrote this bit of code to change your first array (in your "EDIT") into your second array, I'm not saying it's clean, but it works:
sorts the array, then tries to figure out if the countries match, and if they have cities that need to be merged...
//an array of countries, some of which include comma delimited cities wrappedin parentheses
var arrayPlaces = ["china", "country1(city1)", "korea", "country1", "country1(city2)", "country1(city3)", "australia", "korea", "home(delicious)", "home(nacho)", "home(plate)"];
//creates an alphabatized version of the array, to simplify finding matching countries
var arrayPlacesSorted = arrayPlaces.sort();
//defines a regular expression (to search for matches countries)
var hasCity = function (sTemp) {
var re = /\(/;
if (re.test(sTemp)) {
return true;
} else {
return false;
}
};
var countryRe = /(.*?)\(.*?\)/;
var cityRe = /.*?\((.*?)\)/;
//function that loops through array, checks for matching countries, combines/adds cities
var groupCities = function (aTemp) {
var currentCountry,
currentCity,
nextCountry,
nextCity;
for (var i = 0; i < (aTemp.length); i++) {
if (hasCity(aTemp[i])) {
currentCountry = countryRe.exec(aTemp[i])[1];
currentCity = cityRe.exec(aTemp[i])[1];
} else {
currentCountry = aTemp[i];
currentCity = false;
}
if (hasCity(aTemp[i + 1])) {
nextCountry = countryRe.exec(aTemp[i + 1])[1];
nextCity = cityRe.exec(aTemp[i + 1])[1];
} else {
nextCountry = aTemp[i + 1];
nextCity = false;
}
if (currentCountry === nextCountry && nextCity && currentCity) {
aTemp[i] = currentCountry + "(" + currentCity + "," + nextCity + ")";
aTemp.splice(i + 1, 1);
i = 0;
} else if (currentCountry === nextCountry && nextCity) {
aTemp[i] = currentCountry + "(" + nextCity + ")";
aTemp.splice(i + 1, 1);
i = 0;
} else if (currentCountry === nextCountry && currentCity) {
aTemp[i] = currentCountry + "(" + currentCity + ")";
aTemp.splice(i + 1, 1);
i = 0;
} else if (currentCountry === nextCountry) {
aTemp[i] = currentCountry;
aTemp.splice(i + 1, 1);
i = 0;
}
}
return aTemp;
};
var result = groupCities(arrayPlacesSorted);
console.log(result);

Categories