This nodejs file is suppose to read a file line by line. Each line represents and object that I create and add to an array. After finished reading the file it should return that array. Not an expert on javascript but this seems to return an empty array each time. I thought it had something to do with global but creating a temp array and pushing to it in parseline() didn't work either. What am I doing wrong?
var exports = module.exports = {};
const lineReader = require('line-reader');
const Obj = require("./Data")
const Data = Obj.Data;
var records = [];
exports.readAllLines = async function() {
await lineReader.eachLine('./datafile.dat', function(line) {
parseLine(line);
});
return records;
}
function parseLine(inputLine) {
var splitArray = inputLine.split("\t");
var date = new Date(Date.parse(splitArray[0]));
var o= splitArray[1];
var h= splitArray[2];
var l= splitArray[3];
var c= splitArray[4];
var v= splitArray[5];
var dataObject = new Data (date, o, h, l, c, v);
records.push(dataObject);
}
Calling Code
var readFiles = require("./ReadFile.js");
readFiles.readAllLines().then(function(result) {
console.log(result);
});
A simple solution using native apis
var fs = require('fs');
let fileArray = fs.readFileSync(filepath).split('\n');
As per line-reader docs
eachLine and open are compatible with promisify from bluebird
So in order to wait for each line to finish then return data you can install bluebird as per the example and change your code to be like the below
var exports = module.exports = {};
const lineReader = require('line-reader');
const Obj = require("./Data")
const Data = Obj.Data;
Promise = require('bluebird');
var eachLine = Promise.promisify(lineReader.eachLine);
var records = [];
exports.readAllLines = async function() {
await eachLine('./datafile.dat', function (line) {
parseLine(line);
});
return records;
}
function parseLine(inputLine) {
var splitArray = inputLine.split("\t");
var date = new Date(Date.parse(splitArray[0]));
var o= splitArray[1];
var h= splitArray[2];
var l= splitArray[3];
var c= splitArray[4];
var v= splitArray[5];
var dataObject = new Data (date, o, h, l, c, v);
records.push(dataObject);
}
Thanks to jfriends00 and others this is what I came up with. It was indeed a race condition where the array was being returned before the file was read.
var exports = module.exports = {};
const fs = require('fs');
const readline = require('readline');
const Obj = require("./Data")
const Data = Obj.Data;
exports.readAllLines = async function processLineByLine() {
var records = [];
const fileStream = fs.createReadStream('./datafile.dat');
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
for await (const line of rl) {
records.push(parseLine(line));
}
return records;
}
function parseLine(inputLine, records) {
var splitArray = inputLine.split("\t");
var date = new Date(Date.parse(splitArray[0]));
var o= splitArray[1];
var h= splitArray[2];
var l= splitArray[3];
var c= splitArray[4];
var v= splitArray[5];
return new Data(date, o, h, l, c, v);
}
Calling Code
var readFiles = require("./ReadFile.js");
readFiles.readAllLines().then(result => {
console.log(result);
}).catch(exception => {
console.log(exception);
});
Related
I am trying to merge the objects recursively.
what I have
arrayOfObjects = [{a1:{aa:k1}},{a1:{ab:k2}},{a1:{ac:k3}},{a1:{aa:k4}},{a1:{ab:k5}}];
what I need is
{a1:{aa:k1,ab:k2,ac:k3,aa:k4,ab:k5}}
I made a function
function merg(array){
value = {};
if(array.length>0){
$.each(array, function (i) {
value = $.extend(true,{},value,array[i]);
});
}
return value;
};
console.log(merg(arrayOfObjects));
what I get is
{a1:{aa:k1,ab:k2,ac:k3}}
aa:k4,ab:k5 are missing(may due to same key value )
if the deep merge is false I get only one value
value = $.extend({},value,array[i]);
{a1:{aa:k1}}
We can make use of Symbols,
var arr = [{a1:{aa:'k1'}},{a1:{ab:'k2'}},{a1:{ac:'k3'}},{a1:{aa:'k4'}},{a1:{ab:'k5'}}];;
var op = {};
var result = {};
var globalKey;
arr.forEach((ar) => {
var [key, value] = Object.entries(ar)[0];
globalKey = key;
var [innerKey, innerValue] = Object.entries(value)[0];
op[Symbol(innerKey)] = innerValue;
});
result[globalKey] = op;
console.log(result);
this is how my object looks like:
, but I need just one object like
obj = {
var: "DB3,B0",
zahl: "DB3,Int2",
zahl2: "DB3,Int4",
...
...
};
How do I convert it?
I tried different things but it all won't work inside a for loop.
I generate my Object from a string with a code like this:
var text = msg.payload;
var nt = text.split(" ");
var n = nt.length;
var add = [];
var name = [];
var ab = [];
var variables = {};
for (var i = 0; i < n; i++) {
ab[i] = nt[i].split(";");
add[i] = ab[i][0];
name[i] = ab[i][1];
variables[i] = {[name[i]] : add[i]};
}
msg.payloadvars = variables;
return msg;
I think it should be quite simple but I don't come to any solution.
input looks like
DB3,B0;var DB3,Int2;zahl DB3,Int4;zahl2 DB3,Int6;zahl3 DB3,Int8;zahl4
DB3,Int10;zahl5 .....
You could split the string by groups and then for value and key.
var string = 'DB3,B0;var DB3,Int2;zahl DB3,Int4;zahl2 DB3,Int6;zahl3 DB3,Int8;zahl4 DB3,Int10;zahl5',
target = Object.assign(
...string.split(' ').map(s => (([v, k]) => ({ [k]: v }))(s.split(';')))
);
console.log(target);
Use Array.reduce
let str = "DB3,B0;var DB3,Int2;zahl DB3,Int4;zahl2 DB3,Int6;zahl3 DB3,Int8;zahl4 DB3,Int10;zahl5";
let obj = str.split(" ").reduce((a,c) => {
let v = c.split(";");
Object.assign(a, {[v[1]]: v[0]});
return a;
}, {});
console.log(obj);
if you want to make single object then you should try this:
var variables = {};
for (var i = 0; i < n; i++) {
ab[i] = nt[i].split(";");
add[i] = ab[i][0];
name[i] = ab[i][1];
variables[name[i]] = add[i];
}
console.log(variables);
I want to generate a dynamic object and assign value into it. Following is the code
var chunk = "INTERNATIONALISATION#LANGUAGE#DICTIONARY#EN";
var c = chunk.split('#');
var a = {};
So the output should be like this
a["INTERNATIONALISATION"]["LANGUAGE"]["DICTIONARY"]["EN"] = 10;
Tried looping through array but nothing works for now.Please advise.
Try this:
var chunk = "INTERNATIONALISATION#LANGUAGE#DICTIONARY#EN";
var c = chunk.split('#');
var a = {};
var lastKey = c.pop();
c.reduce((obj, key) => obj[key] = obj[key] || {}, a)[lastKey] = 10;
To make it more convenient you can put it in a function:
const dynamicAssign = (object, stringPath, value) => {
const path = stringPath.split('#');
const lastKey = path.pop();
const target = path.reduce((obj, key) => obj[key] = obj[key] || {}, object);
target[lastKey] = value;
};
const a = {};
dynamicAssign(a, "INTERNATIONALISATION#LANGUAGE#DICTIONARY#EN", 10);
Here is my code
Parse.Cloud.define('filters', function(request, response){
var _ = require('underscore');
var customerGeoPoint = request.params.geolocation;
var rating = request.params.rating
var finalList = [];
// var arr = [];
var promises = [];
var query = new Parse.Query('ServiceProvider');
query.withinMiles("geoLocation", customerGeoPoint, 10);
query.find().then(function(spobjs){
return spobjs
}).then(function(newval){
var query2 = new Parse.Query('Customer');
for(i in newval){
query2.withinMiles('geoLocation', newval[i].get('geoLocation'), newval[i].get('serviceRadius'));
var sp = query2.first()
if(sp != null)
{
finalList.push(newval[i]);
}
}
return finalList ;
}).then(function(resval){
var arr = [];
var arr = _.sortBy(resval,'averageRating'); ** This Line doesn't work **
console.log(arr[0]);
return arr ;
}).then(function(checkval){
response.success(checkval);
},function(error){
// console.log(error);
response.error(error);
});
});
In the above code the line which reads "This Line doesn't work" does nothing. I have required underscore.js but still it doesn't sort the array. finalList value gets returned to the then promise after but it doesn't sort it and returns the same value as finalList. Can someone tell me what's the issue with this code?
When sorting parse objects with underscorejs, the iteratee must return the value of the attribute using get()...
var arr = _.sortBy(resval, function(o) { return o.get('averageRating'); });
I would like to convert something like this (used in eg. in class):
var classname = "username_admin color_red strength_good"
into:
myvalues = {
username: 'admin',
color: 'red',
strength: 'good'
}
Here's at present my closest reach:
myvalues = $.map(classname.split(' '),function(el, i) {
var tmp = el.split('_');
var res = {};
res[tmp[0]] = tmp[1];
return res;
});
How to continue? http://jsfiddle.net/4EvWw/
I'd use each() like this because map() returns element of an array as stated in the docs:
jQuery.map( array, callback(elementOfArray, indexInArray) )
Returns: Array
Description: Translate all items in an array or object to new
array of items.
var classname = "username_admin color_red strength_good";
var res = {};
$.each(classname.split(' '),function(i, el) {
var tmp = el.split('_');
res[tmp[0]] = tmp[1];
});
console.log(res);
fiddle here http://jsfiddle.net/4EvWw/1/
You want to use .each rather than .map, and define res outside of the function:
var res = {};
$.each(classname.split(' '),function(i, el) {
var tmp = el.split('_');
res[tmp[0]] = tmp[1];
});
console.log(res);
http://jsfiddle.net/infernalbadger/4EvWw/3/
updated your code to the following http://jsfiddle.net/manuel/4EvWw/2/
var classname = "username_admin color_red strength_good";
var res = {};
$.map(classname.split(' '),function(el, i) {
var tmp = el.split('_');
res[tmp[0]] = tmp[1];
});
console.log(res);