JavaScript generated number is always the same - javascript

I'm trying to generate a number that doesn't replace another already existed number in a json file (orders.json) but in my discord.js bot everytime the command which makes the number keeps making the same number 002 and even creates it again when it already exists replacing the data in the json file which makes alot of issues with me
const json = require('../../orders.json')
const keys = Object.keys(json).map(el => parseInt(el));
const nums = [];
let i = 1;
while (i < 999) {
if (!keys.includes(i)) {
nums.push(`${i}`.padStart(3, '0'));
}
i++;
}
orderID = nums[1]
the generated number is orderID and it's not supposed to replace the same one in the json file
for example the json file has data like this
{
"002": "some data here"
}
now its supposed to create the number 003 since 002 already exists in the json file but it creates the same number replacing the data which causes alot of issues
this is used for a discord bot which writes "orders" by numbers which aren't supposed to do that
EDIT: using Richard's answer
json =
{ "001": "Something"
, "002": { "message": "And more stuff" }
, "003": 42
, "Suddenly": "Okay"
}
const keys = Object.keys(json).map(el => parseInt(el));
console.log(keys);
const nums = [];
i = 1;
while (i < 999) {
if (!keys.includes(i)) {
nums.push(`${i}`.padStart(3, '0'));
}
i++;
}
orderID = nums[0]
console.log(orderID);
with that code the console shows:
1
2
3
NaN
004
now I simply replaced json = { "001": "Something" , "002": { "message": "And more stuff" } , "003": 42 , "Suddenly": "Okay" } with const json = require ('../../orders.json') while the orders.json has this data
{
"001": {
"some data here"
}
}
it only logs "001" which already exists in the json

The first unused number will be nums[0]. Maybe that is what you need to use as the next orderID.
json =
{ "001": "Something"
, "002": { "message": "And more stuff" }
, "003": 42
, "Suddenly": "Okay"
}
const keys = Object.keys(json).map(el => parseInt(el));
console.log(keys);
const nums = [];
i = 1;
while (i < 999) {
if (!keys.includes(i)) {
nums.push(`${i}`.padStart(3, '0'));
}
i++;
}
orderID = nums[0]
console.log(orderID);

Related

How to purify the output of created structured json file in javascript?

I learned how to create structured json file from csv file that generated from google form. However, produced json object contains time header because google form generates that and it saved to csv before creating json object from it.
Here is what I tried to solve this:
let inputCsv = `"Timestamp","Enter First Name:","Enter Middle Initial","Enter Last Name:","Enter UIN:","Are you attending the event?"
"2019/02/22 12:41:56 PM CST","Jonathan","Samson,"Rowe","670168228","No"
"2019/02/22 12:44:56 PM CST","Phil","Aspilla","beltran","6689144343","Yes"`
function convertToJson(inputCsv) {
//inputCsv passed from readfile function
/* Split input string by `,` and clean up each item */
var lines = inputCsv.split('\n');
lines.splice(0,1);
var arrayCsv = [];
for (var line = 0; line < lines.length; line++){
const lineArray = lines[line].split(',').map(s => s.replace(/"/gi, '').trim());
lineArray.splice(0,1);
arrayCsv[line] = lineArray;
}
const outputJson = [];
console.log(arrayCsv);
}
convertToJson(inputCsv)
basically I want to get rid of extra time header (like `2019/02/22 12:41:56 PM CST) every line of input csv file when I create structured json object from it, so here is my desired output:
update: desired output json file
[{
"uin": "123456789",
"studentInfo": {
"firstName": "Jonathan",
"middleName": "Samson",
"lastName": "Rowe",
"rsvpStatus": "Yes"
}
},
{
"uin": "123456788",
"studentInfo": {
"firstName": "phil",
"middleName": "Aspilla",
"lastName": "beltran",
"rsvpStatus": "No"
}
}]
I am not sure how regular expression works in javascript and I want to produce clean structured json object from csv that comes from google form. How can I make this happen? Any way to do this? Thanks
You need to build object in desired format and than push in array.
let inputCsv = `"Timestamp","Enter First Name:","Enter Middle Initial","Enter Last Name:","Enter UIN:","Are you attending the event?"
"2019/02/22 12:41:56 PM CST","Christ","A","coda","670168228","No"
"2019/02/22 12:44:56 PM CST","jack","NA","Harvey","6689144343","Yes"`
function convertToJson(inputCsv) {
const keyMapping = {
"\"Enter First Name:\"" : 'firstName',
"\"Enter Middle Initial\"": 'middleName',
"\"Enter Last Name:\"": 'lastName',
"\"Enter UIN:\"":'uin',
"\"Are you attending the event?\"":'rsvp'
}
var lines = inputCsv.split('\n');
let [keys] = lines
keys = keys.split(',').splice(1,)
lines.splice(0,1);
var arrayCsv = [];
for (var line = 0; line < lines.length; line++){
const lineArray = lines[line].split(',').splice(1,).reduce((o,s,i) =>((o[keyMapping[keys[i]]] = s.replace(/"/gi, '').trim()),o),{});
// here i am creating object in desired format
let obj = {uin:lineArray['uin'],studentInfo:{firstName:lineArray}}
arrayCsv[line] = obj;
}
const outputJson = [];
console.log(arrayCsv);
}
convertToJson(inputCsv)

Iterating over a json array whose key value is dynamic

I have a json structure as:
{
"TestCaseList": [
{
"TC_1": {
"name":"verifyloginpagedetails",
"value":"2"
},
"TC_2": {
"name":"verify registration page details",
"value":"3"
}
}
],
"Summary": {
"v":[
{
"name":"over the ear headphones - white/purple",
"value":1
}
]
}
}
How to extract the values name, value of TC_1 , TC_2 where TC_1 is dynamic i.e. key of TestCaseList?
You can use the Object.keys method to get an array of the keys of an object.
With a single object in the array at "TestCaseList" in your JSON object, this will work:
// jsonObj is your JSON
testCaseKeys = Object.keys(jsonObj.TestCaseList[0]);
If, however, the array at "TestCaseList" contains more than one one element, you can use this to get each set of keys in an individual array:
testCaseKeySets = jsonObj.TestCaseList.map(obj => Object.keys(obj));
I'm sure a more elegant solution exists, but this will do the trick.
var myObj = {
"TestCaseList":
[{
"TC_1":
{"name":"verifyloginpagedetails",
"value":"2"},
"TC_2":
{"name":"verify registration page details",
"value":"3"}
}],
"Summary":{
"v":[{"name":"over the ear headphones - white/purple","value":1}]
}
}
let testCaseListKeys = Object.keys(myObj.TestCaseList[0]);
for(i=0; i < testCaseListKeys.length; i++){
let tclKey = testCaseListKeys[i];
console.log(tclKey + "\'s name = " + myObj.TestCaseList[0][tclKey].name);
console.log(tclKey + "\'s value = " + myObj.TestCaseList[0][tclKey].value);
}
The console.logs are your output. The important values there are the myObj.TestCaseList[0][tclKey].name and the myObj.TestCaseList[0][tclKey].value
** UPDATE **
After answering the question Ananya asked how to do this same thing if the object had a different structure.
Updated Object:
var myObj2 = {
"TestCaseList":
[{
"TC_1":{
"name":"verifyloginpagedetails",
"value":"2"}
},
{
"TC_2":{
"name":"verify registration page details",
"value":"3" }
}],
"Summary":
{
"v":[ {"name":"over the ear headphones - white/purple","value":1} ]
}
}
Updated JavaScript:
for(x=0;x<myObj2.TestCaseList.length;x++) {
let testCaseListKeys = Object.keys(myObj2.TestCaseList[x]);
for(i=0; i < testCaseListKeys.length; i++){
let tclKey = testCaseListKeys[i];
//console.log(tclKey);
console.log(tclKey + "\'s name = " + myObj2.TestCaseList[x][tclKey].name);
console.log(tclKey + "\'s value = " + myObj2.TestCaseList[x][tclKey].value);
}
}

Nodejs - Writing a tab delimited file as json object

Is there a npm module which converts a tab delimited file to a JSON object so i could look up the data by certain properties.
Example: The file would looks like below,
name sex age
A M 20
B F 30
C M 40
D F 50
JSON
[
{
"name": "A",
"sex": "M",
"age": "20"
},
{
"name": "B",
"sex": "F",
"age": "30"
},
/* Etc. */
]
Sometimes i prefer not using node modules so that I can run these scripts without any setup....
IE. nodejs ./convert-to-csv.js
Here is a nodejs script in case you choose not to use a node module.
var fs = require("fs");
fs.readFile("./birthrate_poverty.txt","utf8", function(err, data){
var rows = data.split("\n");
var json = [];
var keys = [];
rows.forEach((value, index)=>{
if(index < 1){// get the keys from the first row in the tab space file
keys = value.split("\t");
}else {// put the values from the following rows into object literals
values = value.split("\t");
json[index-1] = values.map((value, index) => {
return {
[keys[index]]: value
}
}).reduce((currentValue, previousValue) => {
return {
...currentValue,
...previousValue
}
});
}
})
// convert array of objects into json str, and then write it back out to a file
let jsonStr = JSON.stringify(json);
fs.writeFileSync("./birthrate_poverty.json", jsonStr, {encoding: "utf8"})
});
Yes, csvtojson and the delimiter can be anything not only commas.
Example:
const csvFilePath='FILE'
const csv=require('csvtojson')
csv({delimiter:"\t"})
.fromFile(csvFilePath)
.on('json',(jsonObj)=>{
console.log(jsonObj);
})
.on('done',(error)=>{
console.log('end');
})

How to save distinct values in an object in javascript?

I have a bunch of log data which is stored in a variable. Each log value contains a camera name and system ip. I want to create an object which has names as all the distinct system ip's and corresponding value as an array which contains all the camera names corresponding to that system ip. Below is my code ---
$http(req).success(function(data){
$scope.logs = data;
$scope.cameras={};
var v =$scope.logs[0].systemIp;
$scope.cameras["v"]=[];
$scope.cameras["v"].push($scope.logs[0].cameraName);
for(i=1;i<$scope.logs.length;i++){
v=$scope.logs[i].systemIp;
var flag=0;
for(j in $scope.cameras){
if(j==="v")
{
flag=1;
break;
}
}
if(flag==0)
{
$scope.cameras["j"]=[];
$scope.cameras["j"].push($scope.logs[i].cameraName);
}
else if(flag==1)
{
$scope.cameras["v"].push($scope.logs[i].cameraName);
}
}});
And this is what my data looks like --
[{
"_id": "57683fd82c77bb5a1a49a2aa",
"cameraIp": "192.16.0.9",
"cameraName": "garage2",
"systemIp": "192.168.0.2"
},
{
"_id": "57683f8e2c77bb5a1a49a2a9",
"cameraIp": "192.16.0.8",
"cameraName": "garage1",
"systemIp": "192.168.0.2"
},
{
"_id": "57683f5e2c77bb5a1a49a2a8",
"cameraIp": "192.16.0.7",
"cameraName": "Back Door",
"systemIp": "192.168.0.4"
}]
When I print $scope.cameras on my console it gives this as the output -
Object { v: Array[3] }
I want by cameras object to look like this --
{ "192.168.0.2" : [ "garage1" , "garage2"] ,
"192.168.0.4" : [ "Back Door"] }
I am new to javascript, any help is appreciated.
If you are using the Lodash or Underscore library (which I highly recommend), you can just use the _.groupBy() function to do what you are after (along with some other functions to ensure all values are unique).
However, you can also easily implement it yourself:
function groupByDistinct(arr, prop, mapFn) {
mapFn = mapFn || function (x) { return x; };
var output = {};
arr.forEach(function (item) {
var key = item[prop],
val = mapFn(item);
if (!output[key]) {
output[key] = [val];
return;
}
if (output[key].indexOf(val) < 0) {
output[key].push(val);
}
});
return output;
}
Use it for your code like so:
$scope.cameras = groupByDistinct(data, 'cameraIp', function (logEntry) {
return logEntry.cameraName;
});
You are passing a string such as "v" or "j" as your object key, and this string are actually ending being your object key and not the value of this variables as you want. You can use something like this:
for(i=0; i < $scope.logs.length; i++){
var _sysIp = $scope.logs[i].systemIp,
_camName = $scope.logs[i].cameraName;
if(!$scope.cameras.hasOwnProperty(_sysIp)) {
$scope.cameras[_sysIp] = [_camName];
} else if ($scope.cameras[_sysIp].indexOf(_camName) < 0) {
$scope.cameras[_sysIp].push(_camName);
}
}

How can get a count with nested objects with a certain property?

Okay so I'm using angular to get a json saved to my computer to recreate a github gradebook.
I can get the data with my $http request but for the love of me all I want is to get a count of the number of issues with the label "Not Yet".
Here is the javascript:
$http.get('/api/github/repos/issues/all_issues/00All.json')
.then(function(response) {
console.log(response.data[0]);
var counter = 0;
for(var index = 0; index < response.data.length; index++) {
if(response.data[index].labels[0].name == "Not Yet") {
counter++;
};
};
console.log(counter);
});
That's the latest try, I also tried using lodash to get it earlier:
$http.get('/api/github/repos/issues/all_issues/00All.json')
.then(function(response) {
console.log(response);
mile.notYet.width = _.forEach(response.data, function(n){
var counter = 0;
if(_.result(_.find(n.labels[0], 'name')) == "Not Yet") {
counter++;
}
console.log(counter);
counter = ((counter/10) * 100) + '%';
});
});
This is a bit of the json data:
[
{
"url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11",
"labels_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/labels{/name}",
"comments_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/comments",
"events_url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11/events",
"html_url": "https://github.com/TheIronYard--Orlando/2015--SUMMER--FEE/issues/11",
"id": 73013825,
"number": 11,
"title": "00 -- Brace Yourself -- BEN GRIFFITH",
"user": {
"login": "Epicurean306",
"id": 11682684,
"avatar_url": "https://avatars.githubusercontent.com/u/11682684?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/Epicurean306",
"html_url": "https://github.com/Epicurean306",
"followers_url": "https://api.github.com/users/Epicurean306/followers",
"following_url": "https://api.github.com/users/Epicurean306/following{/other_user}",
"gists_url": "https://api.github.com/users/Epicurean306/gists{/gist_id}",
"starred_url": "https://api.github.com/users/Epicurean306/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/Epicurean306/subscriptions",
"organizations_url": "https://api.github.com/users/Epicurean306/orgs",
"repos_url": "https://api.github.com/users/Epicurean306/repos",
"events_url": "https://api.github.com/users/Epicurean306/events{/privacy}",
"received_events_url": "https://api.github.com/users/Epicurean306/received_events",
"type": "User",
"site_admin": false
},
"labels": [
{
"url": "https://api.github.com/repos/TheIronYard--Orlando/2015--SUMMER--FEE/labels/Not%20Yet",
"name": "Not Yet",
"color": "e11d21"
}
],
As you can see the labels property is an object, nested in an array, nested in an object, nested in an array, real lovely. Putting labels[0] results in an error for me each time and doesn't get me a count. Can anybody tell me where I'm messing up please? Thank you!
If you need a solution that includes lodash, which is much more performant than the native high order functions then you can try this solution below:
var size = _(response.data)
.pluck('labels')
.flatten()
.where({ name: 'Not Yet' })
.size();
UPDATE:
If you want it to be more reusable, you can save a reference for a cloned chained sequence and simply supply another array for that cloned sequence.
var data1 = [/*array from data1*/];
var data2 = [/*array from data2*/];
var notYetSequence = _(data1)
.pluck('labels')
.flatten()
.where({ name: 'Not Yet' });
notYetSequence.size(); // returns data 1 count
notYetSequence.plant(data2).size(); // returns data 2 count
You don't need lodash for the task
var cnt = response.data
.map(function(i) { return i.labels; })
// here we extract labels object only (and get an array of arrays of objects)
.map(function(i) { return i.filter(function(l) { return l.name == 'Not yet'; }).length; })
// then for every nested array we return a number of items with
// Not Yet names (and get an array of numbers)
.filter(function(c) { return c > 0; })
// then we filter issues that don't have one (and still get an array of numbers)
.length;
// and finally get length (which is a number)
As a comparison, a plain for loop looks like:
var data = response.data;
var count = 0;
var re = /not yet/i;
for (var a, i=0, iLen=data.length; i<iLen; i++) {
a = data[i].labels;
for (var j=0, jLen=a.length; j<jLen; j++) {
if (re.test(a[j].name)) ++count;
}
}
So really not a lot of code either way, the for loop will be compatible with every browser ever (though using xmlHTTPRequest means at least ed 3+) and fastest… untested of course. ;-)

Categories