Create array and randomize node.js array - node.js

I'm trying to write a cisco webex bot which get all people in the space(room) and randomly write only one name.
I have this code
framework.hears("daily host", function (bot) {
console.log("Choosing a daily host");
responded = true;
// Use the webex SDK to get the list of users in this space
bot.webex.memberships.list({roomId: bot.room.id})
.then((memberships) => {
for (const member of memberships.items) {
if (member.personId === bot.person.id) {
// Skip myself!
continue;
}
let names = (member.personDisplayName) ? member.personDisplayName : member.personEmail;
let arrays = names.split('\n');
var array = arrays[Math.floor(Math.random()*items.length)];
console.log(array)
bot.say(`Hello ${array}`);
}
})
.catch((e) => {
console.error(`Call to sdk.memberships.get() failed: ${e.messages}`);
bot.say('Hello everybody!');
});
});
But this doesn't work.
Also name after i use let arrays = names.split('\n'); separated by space and don't have comma.
I think because of what code doesn't work
Output of console log:
[ 'George Washington' ]
[ 'John' ]
[ 'William Howard Taft' ]
Main question now how to turn output to array?

That's because arrays[Math.floor(Math.random()*items.length)] only assigns an array with length 3. You need to randomise the index and push to array or use a sort function on the original array
var array = arrays.sort((a,b)=>{
return Math.floor(Math.random()*arrays.length);
});
if you are looking to get the output as per you question you can use reduce instead of sort.
var arrays = [ 'George Washington', 'John', 'William Howard Taft'];
var array = arrays.reduce((a,i)=>{
if(!a) a = [];
a.splice(Math.floor(Math.random()*arrays.length), 0, [i]);
return a;
},[]);

Here is how to get a single name from your data, and ensuring it is a string. There are only four names in the array, so run the snippet several times if you keep getting the same name.
// A list of names. Notice that Arraymond is an array; the other names are strings.
const names = [ 'George Washington', 'John', 'William Howard Taft', ['Arraymond'] ];
// Randomize the names
const randomNames = names.sort(() => Math.random() - 0.5);
// Get the first name. Make sure the name is a string (not an array)
const name = randomNames[0].toString();
console.log(name)
A tip: don't name your array "array" or "arrays" - it is not meaningful. Use good naming conventions and meaningful variable names that help others understand what the code is doing.

Related

How to search data in mongodb with dynamic fields using mongoose?

I've a node.js api in which user sends the required fields as an array to be fetched from the mongodb database. I need to find the data of that fields using Find query. I've written forEach statement to loop through that array and got the array elements. But when I try to get the results by inserting the array elements in the query, it doesn't giving the required results. Could any one please help me in resolving the issue by seeing the code below?
templateLevelGraphData: async function(tid,payload){
let err, templateData, respData = [], test, currentValue;
[err,templateData] = await to(Template.findById(tid));
var templateId = templateData.templateId;
payload.variables.forEach(async data=>{
console.log(data); //data has the array elements like variables=["humidity"]
[err, currentValue] = await to(mongoose.connection.db.collection(templateId).find({},{data:1}).sort({"entryDayTime":-1}).limit(1).toArray());
console.log(currentValue);
});
return "success";
}
The expected output is,
[ { humidity: 36 } ]
But I'm getting only _id like,
[ { _id: 5dce3a2df89ab63ee4d95495 } ]
I think data is not applying in the query. But I'm printing the data in the console where it's giving the correct results by displaying the array elements like, humidity. What I need to do to make it work?
When you are passing {data: 1} you are passing an array where is expecting name of column.
You have to create an object where the keys are going to be the elements of the array and set them to 1.
const projection = data.reduce((a,b) => (a[b]=1, a), {});
[...] .find({}, projection) [...]
Actually I got the solution.
for(let i=0;i<payload.variables.length;i++){
var test = '{"'+ payload.variables[i] +'":1,"_id":0}';
var query = JSON.parse(test);
[err, currentValue] = await to(mongoose.connection.db.collection(templateId).find({"deviceId":deviceId},query).sort({"entryDayTime":-1}).limit(1).toArray());
console.log(currentValue); //It's giving the solution
}

NodeJS Iterate through City in JSON, Return Cities and Users in each City

I have the below snippet from a JSON Object that has 3,500 records in it.
[
{
"use:firstName": "Bob",
"use:lastName": "Smith",
"use:categoryId": 36,
"use:company": "BobSmith",
"use:webExId": "Bob.Smith#email.com",
"use:address": {
"com:addressType": "PERSONAL",
"com:city": "US-TX",
"com:country": 1
}
},
{
"use:firstName": "Jane",
"use:lastName": "Doe",
"use:categoryId": 36,
"use:webExId": "Jane.Doe#email.com",
"use:address": {
"com:addressType": "PERSONAL",
"com:city": "US-CA",
"com:country": "1_1"
}
}
{
"use:firstName": "Sam",
"use:lastName": "Sneed",
"use:categoryId": 36,
"use:webExId": "Sam.Sneed#email.com",
"use:address": {
"com:addressType": "PERSONAL",
"com:city": "US-CA",
"com:country": "1_1"
}
}
]
I am using NodeJS and I have been stuck on figuring out the best way to:
1. Iterate through ['use:address']['com:city' to map out and identify all of the Cities. (In the example above, I have two: US-TX and US-CA in the three records provided)
2. Then identify how many records match each City (In the example above, I would have US-TX: 1 and US-CA: 2)
The only code I have is the easy part which is doing a forEach loop through the JSON data, defining userCity variable (to make it easier for me) and then logging to console the results (which is really unnecessary but I did it to confirm I was looping through JSON properly).
function test() {
const webexSiteUserListJson = fs.readFileSync('./src/db/webexSiteUserDetail.json');
const webexSiteUsers = JSON.parse(webexSiteUserListJson);
webexSiteUsers.forEach((userDetails) => {
let userCity = userDetails['use:address']['com:city'];
console.log(userCity);
})
};
I've been searching endlessly for help on the topic and probably not formulating my question properly. Any suggestions are appreciated on how to:
1. Iterate through ['use:address']['com:city' to map out and identify all of the Cities.
2. Then identify how many records match each City (In the example above, I would have US-TX: 1 and US-CA: 2)
Thank you!
You could reduce the webexSiteUsers array into an object that is keyed by city, where each value is the number of times the city occurs. Something like the below should work.
const counts = webexSiteUsers.reduce((countMemo, userDetails) => {
let userCity = userDetails['use:address']['com:city'];
if (countMemo[userCity]) {
countMemo[userCity] = countMemo[userCity] + 1;
} else {
countMemo[userCity] = 1;
}
return countMemo;
}, {});
counts will then be an object that looks like this.
{
"US-TX": 1,
"US-CA": 2
}

array manipulation in node js and lodash

I have two arrays
typeArr = [1010111,23342344]
infoArr={'name':'jon,'age':25}
I am expecting following
[{'name:'jone','age':25,'type':1010111,'default':'ok'},{'name:'jone','age':25,'type':23342344,'default':'nok'}]
Code :
updaterecord(infoArr,type)
{
infoArr.type=type;
response = calculate(age);
if(response)
infoArr.default = 'ok';
else
infoArr.default = 'nok';
return infoArr;
}
createRecord(infoArr,typeArr)
{
var data = _.map(typeArr, type => {
return updaterecord(infoArr,type);
});
return (data);
}
var myData = createRecord(infoArr,typeArr);
I am getting
[{'name:'jone,'age':25.'type':23342344,'default':nok},{'name:'jone,'age':25.'type':23342344,'default':nok}]
with some reason the last record updates the previous one. I have tried generating array using index var but not sure what's wrong it keep overriding the previous item.
how can I resolve this
You are passing the entire infoArr array to your updaterecord() function, but updaterecord() looks like it's expecting a single object. As a result it is adding those properties to the array rather than individual members of the array.
It's not really clear what is supposed to happen because typeArr has two elements and infoArr has one. Do you want to add another to infoArr or should infoArr have the same number of elements as typeArr.
Assuming it should have the same number you would need to use the index the _map gives you to send each item from infoArr:
function createRecord(infoArr,typeArr) {
var data = _.map(typeArr, (type, i) => {
// use infoArr[i] to send one element
return updaterecord(infoArr[i],type);
});
return (data);
}
Edit:
I'm not sure how you are calculating default since it's different in your expected output, but based on one number. To get an array of objects based on infoArray you need to copy the object and add the additional properties the you want. Object.assign() is good for this:
let typeArr = [1010111,23342344]
let infoArr={'name':'jon','age':25}
function updaterecord(infoArr,type){
var obj = Object.assign({}, infoArr)
return Object.assign(obj, {
type: type,
default: infoArr.age > 25 ? 'ok' : 'nok' //or however your figuring this out
})
}
function createRecord(infoArr,typeArr) {
return _.map(typeArr, type => updaterecord(infoArr,type));
}
Result:
[ { name: 'jon', age: 25, type: 1010111, default: 'nok' },
{ name: 'jon', age: 25, type: 23342344, default: 'nok' } ]

collection.find on an item in a subarray

I have the following Object Structure:
[
{
name: "someThing"
,securities: [ {"id": "2241926"} ]
}
]
I want to be able to return all objects in the outer array, that has at least one child secuirty with an id that starts with a value. I have tried a few things and keep running up short. On the mongoo console, this query works:
db.caseSummary.find({"securities.id": /^224.*/i})
We are using ES6, so please apologies for the generator syntax:
const q = require("q");
const startsWith = function(term){
return new RegExp('^' + term + '.*', 'i')
}
const find = function*(collection, criteria){
const command = q.nbind(collection.find, collection),
myCriteria = criteria || {},
results = yield command(myCriteria),
toArray = q.nbind(results.toArray, results) ;
return yield toArray()
}
const searchBySecurity = function*(mongo, term) {
const collection = mongo.collection("caseSummary"),
criteria = {"securities.id": startsWith(term) };
return yield find(collection, criteria);
}
so searchBySecurity(this.mongo, '224') It returns an empty array, it should return the same results as the mongo console. I guess I am missing a pretty basic concept in translating my search criteria or invoking the find writing this in node from raw mongo console query.
Edit 1: to be clear I want to return all parent objects, which have subarrays that contain a value that starts with the term passed in...
Edit 2:
I changed the criteria to be:
criteria = { "securities": {
"$elemMatch": {
"id": "901774109" //common.startsWith(term)
}
}
};
Still the same results.
Edit 3:
Using nodejs - mongodb "version": "1.4.38"
Edit 4:
this ended up not being an issue

node.js: How to make a variable out of a text input?

I want a user to put in a name of a file, then copy the content into an array and save this array with the name of the input filename. Here is the code I am talking about:
The array "items" represents the user input. Right now those items are fed into my function "einlesen" which returns the array with the data. This data is now written into the same array results but I want it to be written into the arrays "GVZ", "TAL", and "XPG". Can someone help me out?
Grateful for every idea :)
Nils
var items = [['GZV', ';', 1, 2], ['TAL', '<|>', 1, 'n'], ['XPG', '<|>', 0, 2]];
var results = [];
items.forEach(function(item) {
einlesen.einlesen(item[0], item[1], item[2], item[3], function(err, result){
results.push(result[1][0]);
console.log(item[0]);
if(results.length == items.length) {
final();
}
})
});
You would be better off using an object instead of an array of arrays:
var items = {
GZV: [...],
TAL: [...],
XPG: [...]
}
for(item in items) {
einlesen.einlesen(...)
}
This way, you can create object properties based on user input. It is not possible to create a variable (presuming you mean variable name?) out of user input.
var newProp = "resultOfInput";
items[newProp] = [...];
console.log(items.resultOfInput) // [...]
If you're doing this, you need to ensure that there's strong validation on the input. For example; if the input contains any spaces this will prevent the property being accessed via dot notation. Worse still, duplicate user input could easily over-ride any existing properties in the array.

Resources