How to add/replace inner object inside JavaScript array - javascript

I have a JavaScript array with the form of
const Rooms = [{
name:"Science",
students:[
{user:"Tom",emotion:"Happy"},
{user:"Marry",emotion:"Angry"},
{user:"Adam",emotion:"Happy"}]
},{
name:"Maths",
students:[
{user:"Stewie",emotion:"Angry"},
{user:"Cleavland",emotion:"Angry"},
{user:"Meg",emotion:"Happy"},
{user:"Peter",emotion:"Angry"},
{user:"Chris",emotion:"Happy"}]
},{
name:"History",
students:[
{user:"Monica",emotion:"Angry"},
{user:"Chandler",emotion:"Happy"},
{user:"Joe",emotion:"Happy"},
{user:"Ross",emotion:"Angry"}]
}];
I need to find a room by name and add/replace it by student when needed. It means I should be able to find the Room (Maths) and add/update student. If student is already there then its emotion should be changed.
This is the code that I tried but it didn't replace the existing student.
Rooms.forEach((e)=>{if(e.name === "Science"){
e.students.push({user:"Tom",emotion:"Surprised"});
}});
How can I search for a particular json and change the existing student or add a new student data (if student is not present)?

Use find in the array of the students:
For instance, to finding "Tom" and updating it:
Rooms.forEach((e)=>{
if(e.name === "Science"){
const tom = e.students.find((student) => student.user === "Tom");
if (!tom)
e.students.push({user:"Tom",emotion:"Surprised"});
else
tom.emotion = "Surprised";
}
});
Note: you may also be using find for finding the room instead of using forEach:
const e = Rooms.find((room) => room.name === "Science");
if (e) {
const tom = e.students.find((student) => student.user === "Tom");
if (!tom)
e.students.push({user:"Tom",emotion:"Surprised"});
else
tom.emotion = "Surprised";
}
}

Related

Array of object - get id for selected user name inside function

const user = [
{name:"jonh" ,id:EAD1234},
{name:"peter" ,id:EAD1235},
{name:"matt" ,id:EAD1236},
{name:"henry" ,id:EAD1237},
]
I have above mentioned array of object,
I want to get selected user id dynamically based on user selection using es6 and javascript e.g. if i select john i should get EAD1234. and it must suitable on large number of records
I tried using filter method
No need to filter through the whole array if the id values are unique:
function getUserByID(id, users) {
for (const u of users) {
if (u.id === id) {
return u;
}
}
return null;
}
If your data really is exceptionally large and it makes sense to store it on the front-end look into using IndexedDB.
Edit: Someone in the comments somewhere mentioned Array.prototype.find(), so you might as well just use the built-in.
function getUserByID(id, users) {
return users.find((u) => u.id === id) || null;
}
If the data is samll,then just combine Array.filter() and Array.map() can do it.
If the data is too large,we can store the data into a database such as mysql or redis,then query it dynamiclly
const user = [
{name:"jonh" ,id:'EAD1234'},
{name:"peter" ,id:'EAD1235'},
{name:"matt" ,id:'EAD1236'},
{name:"henry" ,id:'EAD1237'}
]
let id = 'EAD1234'
let result = user.filter(u => u.id === id).map(u => u.name)
console.log(result)
const user = [
{name:"john" ,id:'EAD1234'},
{name:"peter" ,id:'EAD1235'},
{name:"matt" ,id:'EAD1236'},
{name:"henry" ,id:'EAD1237'},
];
let userName = "john";
let userId = user.filter(user => user.name === userName)[0].name;

Discord.js: Can you filter online and offline users then add them to an array?

So I was wondering if you can take the UserID's from an array, filter them by who is online and add the online members to a variable.
The way most people say on discord is to do something like this but I tried a few different things but they all didn't work, any ideas?
var staff = [
//List of staff ID's will be added here
]
var onlinestaff = staff.filter(/*Check if their status is online*/)
You could do this:
var staffids = [ "736230247556579438", "721834376794472540" ]
var onlineusers = [];
staffids.forEach(async function(u) {
const uu = await client.users.fetch(u)
if(uu.presence.status == "online") {
onlineusers.push(uu.username)
} else {
return
}
})
Also sorry for the variable names, I did this as fast as possible.

Preventing duplicate objects from being added to array?

I am building a little shop for a client and storing the information as an array of objects. But I want to ensure that I am not creating "duplicate" objects. I have seen similar solutions, but perhaps it is my "newness" to coding preventing me from getting the gist of them to implement in my own code, so I'd like some advice specific to what I have done.
I have tried putting my code in an if look, and if no "part", my variable looking for part number, exists in the code, then add the part, and could not get it to function.
Here is the function I am working on:
function submitButton(something) {
window.scroll(0, 0);
cartData = ($(this).attr("data").split(','));
arrObj.push({
part: cartData[0],
description: cartData[1]
});
}
arrObj is defined as a global variable, and is what I am working with here, with a "part" and a "description", which is the data I am trying to save from elsewhere and output to my "#cart". I have that part working, I just want to ensure that the user cannot add the same item twice. (or more times.)
Sorry if my code is shoddy or I look ignorant; I am currently a student trying to figure these things out so most of JS and Jquery is completely new to me. Thank you.
You can create a proxy and use Map to hold and access values, something like this
let cart = new Map([{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }].map(v=>[v.id,v]));
let handler = {
set: function(target,prop, value, reciver){
if(target.has(+prop)){
console.log('already available')
} else{
target.set(prop,value)
}
},
get: function(target,prop){
return target.get(prop)
}
}
let proxied = new Proxy(cart, handler)
proxied['1'] = {id:1,title:'Dog toy'}
proxied['3'] = {id:3,title:'Dog toy new value'}
console.log(proxied['3'])
Assuming the 'part' property is unique on every cartData, I did checking only based on it.
function submitButton(something) {
window.scroll(0, 0);
cartData = ($(this).attr("data").split(','));
if(!isDuplicate(cartData))
arrObj.push({
part: cartData[0],
description: cartData[1]
});
}
const isDuplicate = (arr) => {
for(obj of arrObj){
if(arr[0] === obj.part)
return true;
}
return false;
}
If you want to do the checking on both 'part' and 'description' properties, you may replace the if statement with if(arr[0] === obj.part && arr[1] === obj.description).
Thanks everyone for their suggestions. Using this and help from a friend, this is the solution that worked:
function submitButton(something) {
window.scroll(0,0);
cartData = ($(this).attr("data").split(','));
let cartObj = {
part: cartData[0],
description: cartData[1],
quantity: 1
}
match = false
arrObj.forEach(function(cartObject){
if (cartObject.part == cartData[0]) {
match = true;
}
})
console.log(arrObj);
if (!match) {
arrObj.push(cartObj);
}
Okay, you have multiple possible approaches to this. All of them need you to specify some kind of identifier on the items which the user can add. Usually, this is just an ID integer.
So, if you have that integer you can do the following check to make sure it's not in the array of objects:
let cart = [{ id: 1, title: "Dog toy" }, { id: 2, title: "Best of Stackoverflow 2018" }];
function isInCart(id) {
return cart.some(obj => obj.id === id);
}
console.log(isInCart(1));
console.log(isInCart(3));
Another approach is saving the items by their id in an object:
let cart = { 1: { title: "Dog toy" }, 2: { title: "Best of Stackoverflow 2018" } };
function isInCart(id) {
if(cart[id]) return true;
return false;
}
Try to use indexOf to check if the object exists, for example:
var beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
console.log(beasts.indexOf('aaa'));
// expected output: -1

Pouchdb join / link documents

I have pouchdb/couchbase data with equipment that has user assigned to them.
Equipment with _id and in the equipment doc there is a checkedOutBy with the user._id as the value. Within the employee object there is user.name. When I get the equipment objects how do I also get the user.name and display with the equipment.
I have searched and read about map/reduce that uses emit and do not grasp the idea. My code that i wrote from what i learned is:
by the way I am also using Angularjs.
field = "eq::"
this.getAllEquip = function(field){
function map(doc) {
if (doc.checkedOutBy !== undefined) {
emit(doc.checkedOutBy, {empName : doc.name});
}
}
var result = database.query(map, {include_docs: true,
attachments: true,
startkey: field,
endkey: field + '\uffff'})
.catch(function (err) {
//error stuff here
});
return result
};
I don't see where the two docs would get together. What am i missing? My result is empty.
The equipment json looks like:
{checkedOutBy: "us::10015", description: "3P Microsoft Surface w/stylus & power cord", equipId: "SUR1501", purchaseDate: "", rCost: 1000, id:"eq::10001"}
Emlpoyee json:
{"firstname":"Joe","gender":"male","lastname":"Blow","status":"active","title":"office","type":"userInfo","_id":"us::10015","_rev":"2-95e9f34784094104ad24bbf2894ae786"}
Thank you for your help.
Something like this should work, if I understood the question correctly:
//Sample Array of Objects with Equipment
var arr1=[{checkedout:"abc1",desc:"item1",id:1},
{checkedout:"abc2",desc:"item2",id:2},
{checkedout:"abc3",desc:"item3",id:3},
{checkedout:"abc1",desc:"item1",id:4},
{checkedout:"abc4",desc:"item3",id:5},
{checkedout:"abc6",desc:"item3",id:6}];
//Sample array of objects with Employee - the "id" in arr2 matches with "checkout" in arr1
var arr2=[{name:"john",id:"abc1"},
{name:"jack",id:"abc2"},
{name:"alice",id:"abc3"},
{name:"james",id:"abc4"}];
var result = []; //final result array
//loop through equipment array arr1
arr1.forEach(function(obj) {
var tempObj = obj;
var checkedout_id=obj.checkedout;
//do array.find which will return the first element in the array which satisfies the given function. This is absed on the assumption that that the id is unique for employee and there wont bwe multiple employees with same id (which is the "checkedout" field in equipment. If the employee is not found, it will return undefined.
var foundname = arr2.find(function(obj) {
if (obj.id == checkedout_id)
return obj.name
})
//Create the object to be inserted into the final array by adding a new key called "name", based on the result of above find function
if (foundname != undefined) {
tempObj.name=foundname.name
}
else {
tempObj.name = "Not found";
}
result.push(tempObj);
})
This is my Pouchdb solution, thank you Vijay for leading me to this solution.
First I get all my equipment. Then I use Vijay's idea to loop through the array and add the name to the object and build new array. I found there is a need to go into the .doc. part of the object as in obj.doc.checkedOutBy and tempObj.doc.name to get the job done.
$pouchDB.getAllDocs('eq::').then(function(udata){
var result = [];
//loop through equipment array
udata.rows.forEach(function(obj) {
var tempObj = obj;
var checkedout_id=obj.doc.checkedOutBy;
if (checkedout_id != undefined) {
$pouchDB.get(checkedout_id).then(function(emp){
return emp.firstname + " " + emp.lastname
}).then(function(name){
tempObj.doc.name = name;
});
}
result.push(tempObj);
})
in my service I have:
this.get = function(documentId) {
return database.get(documentId);
};
and:
this.getAllDocs = function(field){
return database.allDocs({
include_docs: true,
attachments: true,
startkey: field,
endkey: field + '\uffff'});
};

How to get result from json object with angular js?

I have a json file and want to count the rows by specific value and load to my page using angular js models.
The json is look like this:
[
{"id":"1","district":"AL"," name":"Lisa Lz","gender":"Female"},
{"id":"2","district":"AL"," name":"Arnord Bk","gender":"Male"},
{"id":"3","district":"NY"," name":"Rony Rogner","gender":"Male"}
]
The json file loaded by $http service.
How can I run such query on the json data:
select COUNT(`name`) as a from tbl_ben where ` gender` = 'Female' and `district` = 'LA';
any idea? 
 
You can't run SQL queries on JSON out-of-the-box, so let's work through it in JavaScript.
We have some data in an array, let's call it people:
let people = [
{"id":"1","district":"AL"," name":"Lisa Lz","gender":"Female"},
{"id":"2","district":"AL"," name":"Arnord Bk","gender":"Male"},
{"id":"3","district":"NY"," name":"Rony Rogner","gender":"Male"}
];
Now, let's filter it down based on their gender and district like in your query:
let filtered = people.filter(p => (p.district === "LA") && (p.gender === "Female"));
Now instead of using COUNT, we can just check the length property of our filtered array:
let count = filtered.length;
We can abstract this code away into a nice function which will do the work for us:
let getCount = (array, predicate) => {
return array.filter(predicate).length;
};
And we can then use this function like so:
let people = [
{"id":"1","district":"AL"," name":"Lisa Lz","gender":"Female"},
{"id":"2","district":"AL"," name":"Arnord Bk","gender":"Male"},
{"id":"3","district":"NY"," name":"Rony Rogner","gender":"Male"}
];
getCount(people, p => p.district === "NY" && p.gender === "Male"); // 1
Note that based on your example data, the count is 0 as you have nobody in the district "LA".

Categories

Resources