formatting path string in javascript - javascript

If you feel that you have to down-vote this question I would be grateful that would comment on it: any feedback is better that no feedback.
I have been trying to format an array of mixed path (unix and windows format) and to remove the root directory in certain case.
But I am wondering if someone could suggest something:
either that makes use of existing function from Nodejs
or that would be more efficient/succint.
source code:
var js = [
"scripts/content.js",
"dist/styles/styles.css",
"dist\\vendor\\scripts\\bootstrap.min.js",
"dist\\vendor\\scripts\\jquery.min.js"
];
var root = 'dist';
var convertPath = function(path) {
return path.replace(/\\/g,"/");
};
var splitted = function(path) {
return path.split('/');
};
var pop = function(arr) {
var l = arr.length;
if( arr[0] === root ){
return arr.splice(1,l-1);
}
return arr;
};
var merge = function(arr) {
return arr.join('/');
};
var length = js.length;
var i = 0;
for(i;i < length; i++){
console.log(js[i] + ' => ' + merge(pop(splitted(convertPath(js[i])))));
}
desired output:
"scripts/content.js => scripts/content.js"
"dist/styles/styles.css => styles/styles.css"
"dist\vendor\scripts\bootstrap.min.js => vendor/scripts/bootstrap.min.js"
"dist\vendor\scripts\jquery.min.js => vendor/scripts/jquery.min.js"
JSBin preview
My aim is to automate the installation of bower components with gulp for a chrome extension project

var output = js.map(function(i){return i + " => " + i.replace(/\\/g, '/').replace(/^dist\//,'');});

Related

javascript using reduce function

I have the below array
["0,5,p1", "24,29,p2", "78,83,p2", "78,83,p3", "162,167,p2" ]
i want the output as ["5,p1","10,p2","5,p3"] , so p1..3 are video files paying time with start and end time . 0,5 mean p1 profile played for 5 sec and so on.
I want to know what profile take what time in total using ECMA script map,reduce function. Here is what i tried but it doesnt work:
var ca = uniqueArray.reduce(function(pval, elem) {
var spl = elem.split(',');
var difference = Math.round(spl[1] - spl[0]);
return difference;
},elem.split(',')[3]);
I dont think it can be done in one pass, but I could be wrong. I'd go for a 2 step...
Reduce the array to get unique map of pX values
Map the result back to an array in the required format
var input = ["0,5,p1", "24,29,p2", "78,83,p2", "78,83,p3", "162,167,p2" ]
var step1 = input.reduce(function(p,c){
var parts = c.split(",");
if(!p[parts[2]])
p[parts[2]] = 0;
p[parts[2]] += parseInt(parts[1],10) - parseInt(parts[0],10);
return p;
},{});
var result = Object.keys(step1).map(function(e){
return step1[e] + "," + e;
});
console.log(result);
You could use es6 map:
arrayWithNumbers.map(a => {var spl = a.split(','); return (spl[1] - spl[0]) + "," + spl[2]})
For a single loop approach, you could use a hash table for same third parts, like 'p1'. If a hash is given, then update the value with the actual delta.
var array = ["0,5,p1", "24,29,p2", "78,83,p2", "78,83,p3", "162,167,p2"],
hash = Object.create(null),
result = array.reduce(function(r, a) {
var parts = a.split(','),
delta = parts[1] - parts[0],
key = parts[2];
if (!(key in hash)) {
hash[key] = r.push([delta, key].join()) - 1;
return r;
}
r[hash[key]] = [+r[hash[key]].split(',')[0] + delta, key].join();
return r;
}, []);
console.log(result);
I have updated the code. Please check now.
var ca = ["0,5,p1", "24,29,p2", "78,83,p2", "78,83,p3", "162,167,p2" ] .reduce(function(result, elem) {
var spl = elem.split(',');
var difference = Math.round(spl[1] - spl[0]);
var found = false
for (var i = 0 ; i < result.length; i++) {
if (result[i].split(',')[1] == spl[2]) {
result[i] = parseInt(result[i].split(',')[0]) + difference+","+spl[2];
found = true;
}
}
if (!found) result.push(difference+","+spl[2]);
return result;
},[]);
console.log("modified array",ca);

How to split and change to different format in javascript

I am new for javascript, I have a one long string i want to split after 3rd commas and change diffferent format. If you are not understand my issues. Please see below example
My string:
var test= "10,Idly(3 Pcs),200,10,Ghee Podi Idly,300";
I want output like this:(Each item should be in next line)
Idly(3 Pcs) - 10 = 200
Ghee Podi Idly - 10 = 300
How to change like this using JavaScript?
Just copy and paste it. Function is more dynamic.
Example Data
var testData = "10,Idly(3 Pcs),200,10,Ghee Podi Idly,300";
Function
function writeData(data){
data = data.split(',');
var tempLine='';
for(var i=0; i<data.length/3; i++) {
tempLine += data[i*3+1] + ' - ' + data[i*3] + ' = ' + data[i*3+2] + '\n';
}
alert(tempLine);
return tempLine;
}
Usage
writeData(testData);
Use split method to transform the string in a array and chunk from lodash or underscore to separate the array in parts of 3.
// A custom chunk method from here -> http://stackoverflow.com/questions/8495687/split-array-into-chunks
Object.defineProperty(Array.prototype, 'chunk_inefficient', {
value: function(chunkSize) {
var array=this;
return [].concat.apply([],
array.map(function(elem,i) {
return i%chunkSize ? [] : [array.slice(i,i+chunkSize)];
})
);
}
});
var test= "10,Idly(3 Pcs),200,10,Ghee Podi Idly,300";
var arr = test.split(',');
var arr = arr.chunk_inefficient(3);
arr.forEach(function (item) {
console.log(item[1]+' - '+item[0]+' = '+item[2]);
});
You can use split to split the string on every comma. The next step is to iterate over the elements, put the current element into a buffer and flush the buffer if it's size is three. So it's something like:
var tokens = test.split(",");
var buffer = [];
for (var i = 0; i < tokens.length; i++) {
buffer.push(tokens[i]);
if (buffer.length==3) {
// process buffer here
buffer = [];
}
}
If you have fix this string you can use it otherwise validate string.
var test= "10,Idly(3 Pcs),200,10,Ghee Podi Idly,300";
var test2= test.split(",");
var temp_Str= test2[1]+' - '+test2[0]+' = '+test2[2]+'\n';
temp_Str+= test2[4]+'-'+test2[3]+' = '+test2[5];
alert(temp_Str);

How to convert a CSV file into a JSON script using Node.js?

test.csv file has:
"Id","UserName","Age"
"01","Sam Smith","33"
"02","Fred Frankly","44"
"03","Zachary Zupers","55"
acpected output: as Json File
[{"id":01,"User Name": " Sam Smith", "Age":"33"},
{"id":03,"User Name": " Fred Frankly", "Age":"44"}
{"id":03,"User Name": "Aachary Zupers", "Age":"55"}
]
I tried to solve like this using node.js
var fs = require("fs");
var data = fs.readFileSync('test.csv');
var stringData=data.toString();
console.log(stringData);
var arrayOne= stringData.split('\r\n');
var header=arrayOne[0].split(',');
var noOfRow=arrayOne.length;
var noOfCol=header.length;
var jArray=[];
var i=0,j=0;
for (i = 1; i < noOfRow-1; i++) {
for (j = 0; j< noOfCol; j++) {
var myNewLine=arrayOne[i].split(',');
jArray.push( '{'+header[j]+':'+myNewLine[j]+'}');
};
};
console.log( jArray);
this is the output I got when I run the above code:
output Image
In the above code I have just tried to show in json script. But If you can do that. Please provide the code to convert the displayed output into a .json file.
Please help me I shall be thankful to you.
As ShanShan mentioned you can leverage an external library for this in a real project, but I've made some modifications to your code that should do what you want in case you're doing this as a learning experience.
I've tried to keep the code roughly the same. There are two major changes. First, rather than construct a string with the content I'm creating an object that stores the data that you're interested in for each row. Because this object is on a per-row level, this is in the outer loop that handles rows. Second, I'm stripping out the first and last character of the header and value text (the quotes). Because you're interepreting the CSV as a string and splitting based on that, it still contains the quotes. In the real world you might want to extract this with a regex or a replace function, but I tried to keep it simple so it uses substring instead.
The code below:
var fs = require("fs");
var data = fs.readFileSync('test.csv');
var stringData=data.toString();
console.log(stringData);
var arrayOne= stringData.split('\r\n');
var header=arrayOne[0].split(',');
var noOfRow=arrayOne.length;
var noOfCol=header.length;
var jArray=[];
var i=0,j=0;
for (i = 1; i < noOfRow-1; i++) {
var obj = {};
var myNewLine=arrayOne[i].split(',');
for (j = 0; j< noOfCol; j++) {
var headerText = header[j].substring(1,header[j].length-1);
var valueText = myNewLine[j].substring(1,myNewLine[j].length-1);
obj[headerText] = valueText;
};
jArray.push(obj);
};
console.log( jArray);
try this:
...
var jArray=[];
var i=0,j=0;
for (i = 1; i < noOfRow-1; i++) {
for (j = 0; j< noOfCol; j++) {
var myNewLine=arrayOne[i].split(',');
jArray.push(JSON.parse( '{'+header[j]+':'+myNewLine[j]+'}'));
};
};
fs.writeFile('test.json', JSON.stringify(jArray), function (err) {
if (err) return console.log(err);
console.log('ok');
});
console.log( jArray);
This should work
var fs = require('fs');
var data = fs.readFileSync('test.csv');
var parsed = data.toString().split('\r\n').splice(1).map(function(d) {
var splitted = d.split(',');
return {
id: parseInt(JSON.parse(splitted[0])),
user_name: JSON.parse(splitted[1]),
age: parseInt(JSON.parse(splitted[2]))
};
});
console.log(parsed);
If you care to not re invent the wheel,
Given a csv such
NAME, AGE
Daffy Duck, 24
Bugs Bunny, 22
you could do like this
var csv = require('csv-parser')
var fs = require('fs')
fs.createReadStream('some-csv-file.csv')
.pipe(csv())
.on('data', function (data) {
console.log('Name: %s Age: %s', data.NAME, data.AGE)
})
see more here

Javascript string manipulation url

My problem is I am trying to extract certain things from the url. I am currently using
window.location.href.substr()
to grab something like "/localhost:123/list/chart=2/view=1"
What i have now, is using the index positioning to grab the chart and view value.
var chart = window.location.href.substr(-8);
var view = window.location.href.substr(-1);
But the problem comes in with I have 10 or more charts. The positioning is messed up. Is there a way where you can ask the code to get the string between "chart=" and the closest "/"?
var str = "/localhost:123/list/chart=2/view=1";
var data = str.match(/\/chart=([0-9]+)\/view=([0-9]+)/);
var chart = data[1];
var view = data[2];
Of course you may want to add in some validation checks before using the outcome of the match.
Inspired by Paul S. I have written a function version of my answer:
function getPathVal(name)
{
var path = window.location.pathname;
var regx = new RegExp('(?:/|&|\\?)'+name+'='+'([^/&,]+)');
var data = path.match(regx);
return data[1] || null;
}
getPathVal('chart');//2
Function should work for fetching params from standard get parameter syntax in a URI, or the syntax in your example URI
Here's a way using String.prototype.indexOf
function getPathVar(key) {
var str = window.location.pathname,
i = str.indexOf('/' + key + '=') + key.length + 2,
j = str.indexOf('/', i);
if (i === key.length + 1) return '';
return str.slice(i, j);
}
// assuming current path as described in question
getPathVar('chart');
You could split your string up, with "/" as delimiter and then loop through the resulting array to find the desired parameters. That way you can easily extract all parameters automatically:
var x = "/localhost:123/list/chart=2/view=1";
var res = {};
var spl = x.split("/");
for (var i = 0; i < spl.length; i++) {
var part = spl[i];
var index = part.indexOf("=");
if (index > 0) {
res[part.substring(0, index)] = part.substring(index + 1);
}
}
console.log(res);
// res = { chart: 2, view: 1}
FIDDLE

Javascript token replace/append

I have a string that looks something like the following 'test:1;hello:five;just:23'. With this string I need to be able to do the following.
....
var test = MergeTokens('test:1;hello:five;just:23', 'yes:23;test:567');
...
The end result should be 'test:567;hello:five;just:23;yes:23' (note the exact order of the tokens is not that important).
Just wondering if anyone has any smart ideas of how to go about this. I was thinking a regex replace on each of the tokens on right and if a replace didn't occur because there was not match just append it. But maybe there is better way.
Cheers
Anthony
Edit: The right side should override the left. The left being what was originally there and the right side being the new content. Another way of looking at it, is that you only keep the tokens on the left if they don't exist on the right and you keep all the tokens on the right.
#Ferdinand
Thanks for the reply. The problem is the efficiency with which the solution you proposed. I was initially thinking down similar lines but discounted it due to the O(n*z) complexity of the merge (where n and z is the number tokens on the left and right respectively) let alone the splitting and joining.
Hence why I was trying to look down the path of a regex. Maybe behind the scenes, regex is just as bad or worse, but having a regex which removes any token from the left string that exists on the right (O(n) for the total amount of token on the right) and then just add the 2 string together (i.e. vat test = test1 + test2) seems more efficient. thanks
I would use join() and split() to create some utility functions to pack and unpack your token data to an object:
// Unpacks a token string into an object.
function splitTokens(str) {
var data = {}, pairs = str.split(';');
for (var i = 0; i < pairs.length; ++i) {
var pair = pairs[i].split(':');
data[pair[0]] = pair[1];
}
return data;
}
// Packs an object into a token string.
function joinTokens(data) {
var pairs = [];
for (var key in data) {
pairs.push(key + ":" + data[key]);
}
return pairs.join(';');
}
Using these, merging is easy:
// Merges all token strings (supports a variable number of arguments).
function mergeTokens() {
var data = {};
for (var i = 0; i < arguments.length; ++i) {
var d = splitTokens(arguments[i]);
for (var key in d) {
data[key] = d[key];
}
}
return joinTokens(data);
}
The utility functions are also useful if you want to extract some keys (say,"test") and/or check for existence:
var data = splitTokens(str);
if (data["test"] === undefined) {
// Does not exist
} else {
alert("Value of 'test': " + data["test"]);
}
The following is what I ended thiking about. What do you guys recon?
Thanks
Anthony
function Tokenizer(input, tokenSpacer, tokenValueSpacer) {
this.Tokenizer = {};
this.TokenSpacer = tokenSpacer;
this.TokenValueSpacer = tokenValueSpacer;
if (input) {
var TokenizerParts = input.split(this.TokenSpacer);
var i, nv;
for (i = 0; i < TokenizerParts.length; i++) {
nv = TokenizerParts[i].split(this.TokenValueSpacer);
this.Tokenizer[nv[0]] = nv[1];
}
}
}
Tokenizer.prototype.add = function(name, value) {
if (arguments.length == 1 && arguments[0].constructor == Object) {
this.addMany(arguments[0]);
return;
}
this.Tokenizer[name] = value;
}
Tokenizer.prototype.addMany = function(newValues) {
for (nv in newValues) {
this.Tokenizer[nv] = newValues[nv];
}
}
Tokenizer.prototype.remove = function(name) {
if (arguments.length == 1 && arguments[0].constructor == Array) {
this.removeMany(arguments[0]);
return;
}
delete this.Tokenizer[name];
}
Tokenizer.prototype.removeMany = function(deleteNames) {
var i;
for (i = 0; i < deleteNames.length; i++) {
delete this.Tokenizer[deleteNames[i]];
}
}
Tokenizer.prototype.MergeTokenizers = function(newTokenizer) {
this.addMany(newTokenizer.Tokenizer);
}
Tokenizer.prototype.getTokenString = function() {
var nv, q = [];
for (nv in this.Tokenizer) {
q[q.length] = nv + this.TokenValueSpacer + this.Tokenizer[nv];
}
return q.join(this.TokenSpacer);
}
Tokenizer.prototype.toString = Tokenizer.prototype.getTokenString;
i am a few years late, but i think this is what you are looking for:
function MergeTokens(input, replace){
var replaceTokens = replace.split(";");
for(i=0; i<replaceTokens.length; i++){
var pair = replaceTokens[i].split(":");
var result = input;
regString = "\\b" + pair[0] + ":[\\w]*\\b";
var reg = new RegExp(regString);
if(reg.test(result)){
result = result.replace(reg, replaceTokens[i]);
}
else{
result = result + replaceTokens[i];
}
}
return result;
}

Categories