access javascript array element by JSON object key - javascript

I have an array that looks like this
var Zips = [{Zip: 92880, Count:1}, {Zip:91710, Count:3}, {Zip:92672, Count:0}]
I would like to be able to access the Count property of a particular object via the Zip property so that I can increment the count when I get another zip that matches. I was hoping something like this but it's not quite right (This would be in a loop)
Zips[rows[i].Zipcode].Count
I know that's not right and am hoping that there is a solution without looping through the result set every time?
Thanks

I know that's not right and am hoping that there is a solution without
looping through the result set every time?
No, you're gonna have to loop and find the appropriate value which meets your criteria. Alternatively you could use the filter method:
var filteredZips = Zips.filter(function(element) {
return element.Zip == 92880;
});
if (filteredZips.length > 0) {
// we have found a corresponding element
var count = filteredZips[0].count;
}
If you had designed your object in a different manner:
var zips = {"92880": 1, "91710": 3, "92672": 0 };
then you could have directly accessed the Count:
var count = zips["92880"];

In the current form, you can not access an element by its ZIP-code without a loop.
You could transform your array to an object of this form:
var Zips = { 92880: 1, 91710: 3 }; // etc.
Then you can access it by
Zips[rows[i].Zipcode]
To transform from array to object you could use this
var ZipsObj = {};
for( var i=Zips.length; i--; ) {
ZipsObj[ Zips[i].Zip ] = Zips[i].Count;
}

Couple of mistakes in your code.
Your array is collection of objects
You can access objects with their property name and not property value i.e Zips[0]['Zip'] is correct, or by object notation Zips[0].Zip.
If you want to find the value you have to loop

If you want to keep the format of the array Zips and its elements
var Zips = [{Zip: 92880, Count:1}, {Zip:91710, Count:3}, {Zip:92672, Count:0}];
var MappedZips = {}; // first of all build hash by Zip
for (var i = 0; i < Zips.length; i++) {
MappedZips[Zips[i].Zip] = Zips[i];
}
MappedZips is {"92880": {Zip: 92880, Count:1}, "91710": {Zip:91710, Count:3}, "92672": {Zip:92672, Count:0}}
// then you can get Count by O(1)
alert(MappedZips[92880].Count);
// or can change data by O(1)
MappedZips[92880].Count++;
alert(MappedZips[92880].Count);
jsFiddle example

function getZip(zips, zipNumber) {
var answer = null;
zips.forEach(function(zip){
if (zip.Zip === zipNumber) answer = zip;
});
return answer;
}
This function returns the zip object with the Zip property equal to zipNumber, or null if none exists.

did you try this?
Zips[i].Zip.Count

Related

Iterating over and comparing properties of two arrays of objects

I have set up a HBS helper which takes in two arrays of objects (users privileges). What I want to do is compare them and inject back into the template the privileges the user does and doesn't have.
Presently I can compare the names of the privileges with the following code:
hbs.registerHelper('selected', function(option, value){
var i;
var j;
var privName;
var userPriv;
var privObj = new Object();
var privArray = [];
for(i in option){
console.log('each ' + JSON.stringify(option[i]));
privName = option[i].privname;
for (y in value){
if(privName == value[y].privname){
userPriv = value[y].privname;
console.log('user has the following privileges', value[y].privname);
privObj = new Object();
privObj.name = userpriv;
privObj.id = value[y]._id;
privObj.state = 'selected';
privArray.push(privObj);
} else if (privName != value[y].privname){
console.log('user doesnt have priv ', privName);
privObj = new Object();
privObj.name = option[i].privname;
privObj.id = option[i].id;
privObj.state = '';
privArray.push(privObj);
}
}
}
console.log('privileges array ', privArray);
return privArray;
});
This works OK when the user only has one privilege, however when the user has more than one, for example two privileges, it returns the privileges twice. If the user has 3, thrice and so on. I know this is because the array is looping again because their are 2, 3 etc in the .length. However I can't seem to find an adequate solution.
Any help?
P.S. it would be nice if the Array.includes() method allowed you to search object properties.
The problem creating new objects the way you did is that for each property you add to your privilege-entity you will have to return to that function and set that property as well. You can instead just add/alter the state property of the existing objects:
hbs.registerHelper('selected', function(option, value) {
var names = option.map(function(opt) {
return opt.privname;
});
value.forEach(function(val) {
val.state = names.indexOf(val.privname) >= 0 ? 'selected' : '';
});
return value;
});
Basically:
The variable names is being mapped to be an array only with the privnames. You can check by using console.log(names).
The Array.forEach() function is helpful in this case because you just need to iterate over each object inside value and set its state-property.
To check if the privname exists, you just need to check the index in the previous names-mapped-array. For such a simple thing I used ternary operator (?:).
Finally, you return value, which is the array containing the objects you had updated.

How to remove all characters before specific character in array data

I have a comma-separated string being pulled into my application from a web service, which lists a user's roles. What I need to do with this string is turn it into an array, so I can then process it for my end result. I've successfully converted the string to an array with jQuery, which is goal #1. Goal #2, which I don't know how to do, is take the newly created array, and remove all characters before any array item that contains '/', including '/'.
I created a simple work-in-progress JSFiddle: https://jsfiddle.net/2Lfo4966/
The string I receive is the following:
ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC
ABCD/ in the string above can change, and may be XYZ, MNO, etc.
To convert to an array, I've done the following:
var importUserRole = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',');
Using console.log, I get the following result:
["ABCD", "ABCD/Admin", "ABCD/DataManagement", "ABCD/XYZTeam", "ABCD/DriverUsers", "ABCD/RISC"]
I'm now at the point where I need the code to look at each index of array, and if / exists, remove all characters before / including /.
I've searched for a solution, but the JS solutions I've found are for removing characters after a particular character, and are not quite what I need to get this done.
You can use a single for loop to go through the array, then split() the values by / and retrieve the last value of that resulting array using pop(). Try this:
for (var i = 0; i < currentUserRole.length; i++) {
var data = currentUserRole[i].split('/');
currentUserRole[i] = data.pop();
}
Example fiddle
The benefit of using pop() over an explicit index, eg [1], is that this code won't break if there are no or multiple slashes within the string.
You could go one step further and make this more succinct by using map():
var importUserRole = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',').map(function(user) {
return user.split('/').pop();
});
console.log(currentUserRole);
You can loop through the array and perform this string replace:
currentUserRole.forEach(function (role) {
role = role.replace(/(.*\/)/g, '');
});
$(document).ready(function(){
var A=['ABCD','ABCD/Admin','ABCD/DataManagement','ABCD/XYZTeam','ABCD/DriverUsers','ABCD/RISC'];
$.each(A,function(i,v){
if(v.indexOf('/')){
var e=v.split('/');
A[i]=e[e.length-1];
}
})
console.log(A);
});
You could replace the unwanted parts.
var array = ["ABCD", "ABCD/Admin", "ABCD/DataManagement", "ABCD/XYZTeam", "ABCD/DriverUsers", "ABCD/RISC"];
array = array.map(function (a) {
return a.replace(/^.*\//, '');
});
console.log(array);
var importUserRole = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',');
for(i=0;i<currentUserRole.length;i++ ){
result = currentUserRole[i].split('/');
if(result[1]){
console.log(result[1]+'-'+i);
}
else{
console.log(result[0]+'-'+i);
}
}
In console, you will get required result and array index
I would do like this;
var iur = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC',
arr = iur.split(",").map(s => s.split("/").pop());
console.log(arr);
You can use the split method as you all ready know string split method and then use the pop method that will remove the last index of the array and return the value remove pop method
var importUserRole = ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',');
for(var x = 0; x < currentUserRole.length; x++;){
var data = currentUserRole[x].split('/');
currentUserRole[x] = data.pop();
}
Here is a long way
You can iterate the array as you have done then check if includes the caracter '/' you will take the indexOf and substact the string after the '/'
substring method in javaScript
var importUserRole = 'ABCD,ABCD/Admin,ABCD/DataManagement,ABCD/XYZTeam,ABCD/DriverUsers,ABCD/RISC';
var currentUserRole = importUserRole.split(',');
for(var x = 0; x < currentUserRole.length; x++){
if(currentUserRole[x].includes('/')){
var lastIndex = currentUserRole[x].indexOf('/');
currentUserRole[x] = currentUserRole[x].substr(lastIndex+1);
}
}

remove items from array with the same id one by one

the problem is that I have multiple objects with the same id. As you can see this works when it comes to removing all the items with the same id. How I can remove the objects one by one no matter if they are the same ID...thanks
individualObjects:[],
actions:{
increment:function(){
var obj = this.get('object');
this.get('individualObjects').pushObject(obj);
},
decrement:function(){
var obj = this.get('object');
var filter = this.get('individualObjects').findBy('obj_id', obj.get('obj_id'));
this.get('individualObjects').removeObject(filter);
}
}
Well to filter array you would need to use Array.filter to find out the items that do not belong in the "individualObjects" and later simply remove them by using "removeObjects"
decrement:function(){
var objects = this.get('individualObjects')
var notWanted = objects.filterBy('obj_id', this.get('object.obj_id'));
this.get('individualObjects').removeObjects(notWanted);
}
and solution 2
decrement:function(){
var removeObj = this.get('object');
var objects = this.get('individualObjects')
// As the condition is true given object is returned
var notWanted = objects.filter(obj => { return obj.get('obj_id') === removeObj.get('obj_id')  });
this.get('individualObjects').removeObjects(notWanted);
}
Ok so you want to remove items one by one. Weird but can be accomplished
first get the length for
var notWantedCount = objects.filterBy('obj_id', this.get('object.obj_id')).length;
Now
for(var i=0; i <= notWantedCount; i++) {
var toRemove = individualObjects.findBy('obj_id', obj.get('obj_id'));
individualObjects.removeObject(toRemove);
// Make some custom actions one by one.
}
I don't know ember, but you'll want to do a foreach on the array, and then test for id on each one. It should be something like this:
decrement:function(){
var obj = this.get('object');
self = this;
this.get('individualObjects').each(function(individualObject) {
if (individualObject.get('obj_id') == obj.get('obj_id'))
... you want to do something here? ...
self.get('individualObjects').removeObject(individualObject);
}
}
That way you can remove each object individually. Running any necessary code before or after it's removed. If you want to sort it first, you can do that before running the each function.

Javascript search if LocalStorage variable exists

I am programming a chat system. I always make a Localstorage variable when a new chat is opened. Created like this:
localStorage.setItem("chat_"+varemail, data);
Now i want to check how many of them I have so something like:
"chat_"+... count.
How can I do this?
You'd grab the array of keys of the localStorage object, and use Array.filter to grab only the items starting with "chat_":
var length = Object.keys(localStorage).filter(function(key) {
return /^chat_.+/.test(key);
}).length;
Here's a JSFiddle
Try something like this, loop through all items in localStorage and match against your pattern
function getChatCount(){
var chatCount = 0;
for(item in localStorage){
if(item.indexOf('chat_') > -1) chatCount++;
}
return chatCount;
}
Local storage is based on key, value pairs. AFAIK, you wouldn't be able to retrieve all values with a certain prefix.
One potential solution would be to store an object that contains these. Based on your needs you could store the objects in an array or object and then retrieve the entire set and find the count.
For example:
var chats = { count: 0 };
chats["chat_"+varemail] = data;
chats.count += 1;
localStorage.setItem('chats', data);
Then if you want a count, you would retrieve the object:
var chats = localStorage.getItem('chats');
//chats.count would give you the count.
Although, this would mean you have to manually maintain the count variable when adding or removing data. If you don't need the indexing ability, you could add the chats to an array and store that.
EDIT: It is possible to find properties with a certain prefix, as seen in an answer to this question.
I would offer to convert to localStorage.setItem("chat", JSON.stringify(stack)), where stack is an array of chat objects. This way, you have access to an array of chats which you can count, search within, etc.
Something like:
var chatStore =
{
Count: function () {
var stack = JSON.parse(localStorage.getItem("chats"));
if (!stack)
return 0;
return stack.length;
},
Peek: function () {
var stack = JSON.parse(localStorage.getItem("chats"));
if (!stack)
stack = [];
if (stack.length > 0)
return stack.pop();
},
Push: function (token) {
var stack = JSON.parse(localStorage.getItem("chats"));
if (!stack)
stack = [];
stack.push(token);
localStorage.setItem("chats", JSON.stringify(stack));
},
// more methods to you might wish to implement: search, insert, etc.
}
// usage:
chatStore.Push(chatObject); // sets the last chat
chatStore.Peek(); // gets the last chat

arranging elements in to a hash array

I am trying to break a javascript object in to small array so that I can easily access the innerlevel data whenever I needed.
I have used recursive function to access all nodes inside json, using the program
http://jsfiddle.net/SvMUN/1/
What I am trying to do here is that I want to store these in to a separate array so that I cn access it like
newArray.Microsoft= MSFT, Microsoft;
newArray.Intel Corp=(INTC, Fortune 500);
newArray.Japan=Japan
newArray.Bernanke=Bernanke;
Depth of each array are different, so the ones with single level can use the same name like I ve shown in the example Bernanke. Is it possible to do it this way?
No, you reduce the Facets to a string named html - but you want an object.
function generateList(facets) {
var map = {};
(function recurse(arr) {
var join = [];
for (var i=0; i<arr.length; i++) {
var current = arr[i].term; // every object must have one!
current = current.replace(/ /g, "_");
join.push(current); // only on lowest level?
if (current in arr[i])
map[current] = recurse(arr[i][current]);
}
return join;
})(facets)
return map;
}
Demo on jsfiddle.net
To get the one-level-data, you could just add this else-statement after the if:
else
map[current] = [ current ]; // create Array manually
Altough I don't think the result (demo) makes much sense then.

Categories

Resources