I'm new to JavaScript and I want a Data Structure for my JavaScript code which stores Student data as key value pairs. The key is the student Registration number and the value is the students name.What I'm thinking is to create a JavaScript object as follows and store data as follows
let Student={
001A:"John",
002A:"Mathew"
};
Is this approach is correct? And if it is correct suppose a way to dynamically add key value pairs to that. Thank you
That would be an object literal. You'd want the key to be a string, but other than that you've basically got it. You can dynamically add properties using bracket syntax. I've attached a small snippet to give you an idea of how it works. :)
let Student={
"001A":"John",
"002A":"Mathew"
};
Student["003A"] = 'Jessica';
Object.entries(Student).forEach(entry => console.log(entry) );
The approach is correct. Given
const students={
'001A': 'John',
'002A': 'Mathew',
};
(Note: It's a good idea to keep your key as a string to prevent collisions with reserved keywords)
To read from the structure you can access the given record via
console.log(students['001A']); // => 'John'
To add new records dynamically, you just add a new property and assign it the desired value:
students['007'] = 'Ben';
which results in
console.log(students);
// =>
{
'001A': 'John',
'002A': 'Mathew',
'007': 'Ben',
};
To delete a given record you can do either
delete students['007'];
or
students['007'] = undefined;
The first option is a little "cleaner" as it completely deletes the given key, along with its assigned data.
Keep in mind that the data will be removed once you reload the page.
Related
I have started to learn angular recently. I came across a code as follows.
Consider this.members as an array of objects. There is an object which has the username bob. I am trying to get that particular object using the below code.
const data = this.members.find(x=>x.userName===username);
So there an object inside the array and I have an object stored in my const data, My doubt is that will both (the object in the array and the object in the const data ) have the same memory address. If someone could answer why changing the const data is also getting reflected in the this.members array. It would be a great help. You can also share some resources if I need to go through them to understand them better.
To shortly answer your question, yes. The data object will have a reference to the object inside this.members.
If you want to prevent that, there are multiple ways I'm sure, but one of them is to use Object.assign.
Example:
let data: any = {};
Object.assign(data, this.members.find(u => u.username === 'bob'));
console.log(this.members); // For example: [{username: 'bob'},{username: 'randy'}]
data.username = 'alex';
console.log(this.members); // Still shows [{username: 'bob'},{username: 'randy'}]
console.log(data); // {username: 'alex'}
Notice here that I am using TypeScript since you mentioned you're working with Angular.
When using Object.assign, a copy of the enumerable properties will be made and assigned to your variable without referencing the source.
See MDN Docs for more details.
Another simple way is to use the spread operator.
let data: any = {};
const foundUser = this.members.find(u => u.username === 'bob');
if (foundUser) {
data = {...foundUser};
}
This will create a new object with the properties from the foundUser.
You can easily try it out.
const members = [
{ username: 'bob' },
{ username: 'daniel' },
];
const data = members.find(x=>x.username==='bob');
data.username = 'bobby';
console.log(members);
That prints
[ {
"username": "bobby" }, {
"username": "daniel" } ]
So yes, changing data will change the array.
The answer for this question is that Arrays in javascript are mutable which means they are reference type which means when I encounter the below line
const data = this.members.find(x=>x.userName===username);
const data will have the same memory location as that of bob in the array. As we all know that if we change data at a memory location every variable/object referring to that memory location will also change as they all point to the same memory location. Hence the array gets updated even though I assign a part of the array and make changes to that part alone.
Note: The above was my expected behavior. if you want the opposite behavior like if you need the const data and this.members to be independent you can use
Copy Array
or you can refer to Maher's answer in the same page.
I am using Object.assign method to change the structure of my JSON.
let opVal = []
data[item].map(function(key,value) {
opAllVal = key;
finalResult = Object.assign(data, {[item]: [opAllVal]});
});
Here data contains the JSON. And key contains more than one value at a time. I want to send all the values that are coming in key in the below format.
For e.g., If item is sampleKey and values in key are sampleValue1 and sampleValue2, so they should be sent as -
"sampleKey":["sampleValue1","sampleValue2"]
but with the above code, these are sending as -
"sampleKey":["sampleValue2"]
Only the last value is getting sent everytime, not all the values which are coming in key. Can anyone help me in sending all the values of key to item in the above format.
Thanks in advance...
Every time you use the code finalResult = Object.assign(data, {[item]: [opAllVal]});, you are overwriting the previous version of data[item] ignoring the previous content, in other words, data[item] is always set to an array with a single element that is key.
Btw, by the code it's not very clear what you'd like to do. If I understood you can have an input like this:
data = {
... //other params
"sampleKey": [
"sampleValue1",
"sampleValue2"
]
}
What's the expected output?
For what I see in the code it will be better to use forEach instead of map and the name of the variables in forEach should be inverted (value, key) instead of (key, value) as map and forEach call both the callback by passing before the value and after the key.
Also I suggest to change the tag in your question as it is not related to reactjs but it's related to js and independent from react (if you do this you'll receive more visualisations and more answers).
I'm calling an external service and I get the returned domain object like this:
var domainObject = responseObject.json();
This converts the response object into a js object. I can then easily access a property on this object like this
var users = domainObject.Users
Users is a collection of key/value pairs like this:
1: "Bob Smith"
2: "Jane Doe"
3: "Bill Jones"
But CDT shows users as Object type and users[0] returns undefined. So how can I get a handle to the first item in the collection? I'm assuming that some type of type cast is needed but not sure how I should go about doing this
UPDATE
Here is one way I could access the values:
//get first user key
Object.keys(responseObject.json().Users)[0]
//get first user value
Object.values(responseObject.json().Users)[0]
But I need to databind through ng2 so I was hoping for a simpler way like this:
<div>
<div *ngFor="let user of users">
User Name: {{user.value}}
<br>
</div>
</div>
Maybe I should just create a conversion function in my ng2 component which converts the object into what I need before setting the databinding variable?
UPDATED ANSWER
So after scouring through a few docs I found the "newish" Object.entries() javascript function. You can read about it here. Pretty cool.
Anyways, give this a try. I am ashamed to say that I don't have time to test it, but it should get you going in the right direction.
usersArray = []
// Turn Users object into array of [key, value] sub arrays.
userPairs = Object.entries(users);
// Add the users back into an array in the original order.
for (i=0; i < userPairs; i++) {
usersArray.push(_.find(userPairs, function(userPair) { return userPair[0] == i }))
}
ORIGINAL ANSWER
I would use either underscore.js or lodash to do this. Both are super helpful libraries in terms of dealing with data structures and keeping code to a minimum. I would personally use the _.values function in lodash. Read more about it here.. Then you could use users[0] to retrieve the first item.
The only caveat to this is that lodash doesn't guarantee the iteration sequence will be the same as it is when the object is passed in.
users = _.values(users);
console.log(users[0]);
How about this:
let user= this.users.find(() => true)
This should return the "first" one.
If your initial object is just a plain object, how do you know it is sorted. Property members are not sorted, ie: looping order is nor guaranteed. I´d extract the user names into an array and the sort that array by the second word. This should work (as long as surnames are the second word, and only single spaces are used as separators).
var l=[];
for(var x in users) {
push.l(users[x]);
}
var l1=l.sort ( (a,b) => return a.split(" ")[1]<b.split(" ")[1]);
I have an object array:
user :[
{
name: String,
username: String
}
]
I want to view every change either to name or username.
I found underscore _.pluck only does the trick for one property (_.pluck(user, 'name')
Is there another way to have the list of both values?
With pluck you can only use one property, it simply isn't made to retrieve multiple. The method you would want to use is map, as suggested in this relevant question + answer: How to pluck multiple attributes from a Backbone collection?
Assuming you want the following output [['nameA','usernameA'],['nameB','usernameB'],...]], you could use map in the following manner:
var myResult = users.map(function(user) {
return [user.name, user.username];
});
NOTE: I changed the variable user to users to make more sense with your data.
I need to store data temporarily at the client-side to allow users to add, edit or delete items without having to query the server for each of these actions; just when the user finishes adding items and clicks on the Add button, the list is sent to the server to be saved permanently.
This image describes what I want to achieve.
I know I have to use arrays in JavaScript, but I don't know how to create one to store objects (in this case Detail which contains :id, price and description).
I hope you can help me out.
Thanks in advance.
PS: I'm using JSP and... sorry for my English
Sure, since it's a table it makes sense to have an array of objects. Note that an object is surrounded by curly braces and an array is surrounded by brackets:
var myArray = []; // Initialize empty array
var myObject = {}; // Initialize empty object
This should accomplish what you need:
// Initialize variables
var newEntry, table = [];
// Create a new object
newEntry = {
id: '',
price: '',
description: ''
};
// Add the object to the end of the array
table.push(newEntry);
Which is the same as this:
// Initialize array
var table = [];
// Create object and add the object to the end of the array
table.push({
id: '22',
price: '$222',
description: 'Foo'
});
You can now access properties like this:
table[0].id; // '22'
On modern browsers, if you want the data to persist across sessions (like cookies) you could use the sessionStorage or localStorage objects.
When you want to send the data to the server, you'll send a JSON version of the table across the wire:
var data = JSON.stringify(table);
You can create an Array of your custom Detail objects pretty easily with object literals:
var details = [];
details.push({id:'abc1234', price:999.99, description:'Tesla Roadster'});
details.push({id:'xyz5678', price:129.99, description:'Land Rover'});
Then you can post your data to the server when the user clicks "Add."
Sounds like a good job for JSON.