I want to loop through this object and add the 'loc' value to an array if their side = 2. What am I doing wrong?
2025 is the the room object and the entire things is rooms.
//Object
{
"2025": {
"tom": {
"side": 1,
"loc": 111
},
"billy": {
"side": 2,
"loc": 222
},
"joe": {
"side": 2,
"loc": 333
},
"bob": {
"side": 1,
"loc": 444
}
}
}
//Code
var side2 = [];
for (var key in rooms[room]) {
if (rooms[room].hasOwnProperty(key)) {
var obj = rooms[room][key];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
if(prop == 'loc') {
if(obj[prop] == 2) {
side2.push(key);
}
}
}
}
}
}
console.log(side2);
You want to push when the side value is 2, so you want to check side and not loc. Then you can simply push obj.loc
...
if (obj.hasOwnProperty(prop)) {
if(prop == 'side') {
if(obj[prop] == 2) {
side2.push(obj.loc);
}
}
}
...
Fiddle Example
That being said you can shorten this code quite a bit, removing unneeded looping and work you can shorten all your code to simply:
for (var key in rooms[room]) {
var item = rooms[room][key];
if(item.side == 2)
side2.push(item.loc)
}
Fiddle Example
From your statement, you want to push the value of loc property to the array side2 if the value of side property is 2.
But in your code
if(prop == 'loc') {
if(obj[prop] == 2) {
side2.push(key);
}
}
You are comparing the value of loc property to be 2, not the value of side property. you probably need something like
if(prop == 'side') {
if(obj[prop] == 2) {
side2.push(obj['loc']);
}
}
As mentioned in comments and other answers, you are looking for a loc property of 2 which doesn't exist. So the immediate problem can be solved by replacing loc with side (assuming that's what you want).
But your code can be simplified. Looping at the top level is fine. However, the entire nested loop part of your code:
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
if(prop == 'loc') {
if(obj[prop] == 2) {
side2.push(key);
}
}
}
}
can be replaced with
if (obj.side == 2) side2.push(key);
In other words, you don't need to loop through an object's properties to find a particular one (side in this case). You can just access it, with obj.side.
You can also conceive of this problem as wanting to filter the list of rooms down to those with people with a loc of 2, in which case you could write:
Object.keys(rooms) . filter(hasPeopleWithLoc(2))
where
function hasPeopleWithLoc(loc) {
return function(roomKey) {
var room = rooms[roomKey];
return Object.keys(room) . some(function(personKey) {
return room[personKey].loc === loc;
});
};
}
Note that this code will leave you with just one entry for a room in the result if anyone in that room has a loc of 2. Your original code behaves slightly differently; it puts an entry for the room in the result for each person in that room with the desired loc.
Related
I have an array that is created from an API call.
Here is how I make this array-
var data5 = ko.observableArray(); /*Most important thing to make the data array observable otherwise it will not show the data of the REST API*/
var arrow = [];
function practiceData() {
// var data = [];/**/
$.getJSON("REST API").then(function(dataset) {
$.each(dataset, function(index, value) {
//console.table((dataset));
//console.log(value.change);
data5.push(value); // PUSH THE VALUES INSIDE THE ARRAY.
arrow.push(value.change);
console.log("arrow", arrow);
arrow.forEach(function(value) {
if (value == 0) {
$("#triangle-down-small").hide();
$("#triangle-up-small").hide();
console.log("rgjak")
console.log(value);
// document.getElementById("navTabBar").style.visibility = "none";
} else if (value < 0) {
// $("#triangle-down-small").hide();
$("#triangle-up-small").hide();
console.log("hcdsb")
console.log(value);
}
});
});
});
}
console.log(arrow)-
arrow (1) [0]
arrow (2) [0, 0]
arrow (3) [0, 0, -100]
JSON Response Structure-
[
{
"change": 0,
"count": 6,
"duration": 4,
"prevcount": 6,
"subcategory": "Consultancy"
}
]
I am not able to iterate through the array as for the if-else condition the .hide() function works for just the if condition not for the else-if.
Any help is appreciated.
Thanks in advance.
Just for your reference, Move loop after $.each. But no point of coding like this.Bad practice
function practiceData() {
$.getJSON("REST API").then(function (dataset) {
$.each(dataset, function (index, value) {
data5.push(value); // PUSH THE VALUES INSIDE THE ARRAY.
arrow.push(value.change);
});
console.log("arrow", arrow);
arrow.forEach(function (value) {
if (value == 0) {
console.log("rgjak");
console.log(value);
} else if (value < 0) {
console.log("hcdsb");
console.log(value);
}
});
});
}
The array foreach function is very simple and basic, so there is nothing wrong with that.
I guess your problem is that your data structure not being consistent or you have a logic problem in your code.
You should make sure to always check that the values you push into the array exist and are numbers.
e.g
if (!value || typeof value.change === 'undefined') {
return ;
}
Also, given your json response data, [0, 0, -100]
both if and else statements will run and both buttons will be hidden.
As long as there is one zero in your array, both buttons will be hidden.
I am trying to compare two array of object values based on the specific key. Two object has same keys based on that i have to check whether the values are equal or not. One array is actual JSON object and the second one is test data, we have to verify the test data with JSON object and moreover if the test data value is same, it might have some extra space we need to trim that value as well.
var actualObject= [
{
"q1": "componentWillMount"
},
{
"q2": "willComponentUpdate"
},
{
"q3": "setState"
},
{
"q4": "componentUpdated"
}
]
Var testData =[
{q1: "componentWillMount"},
{q2: "willComponentUpdate"},
{q3: " PropTypes"},
{q4: "componentDidMount"}]
I will get the testData values from the Html code, on selection of radio buttons. Now i need to check how many answer are correct with actual JSON.
JS Code for it:
var marks= 0;
var wrong = 0;
for(var k =0 ; k<actualObject.length;k++){
if(JSON.stringify(actualObject[k]) == JSON.stringify(testData[k])){
marks++;
}
else {
wrong++;
}
}
var actualObject = [{
"q1": "componentWillMount"
},
{
"q2": "willComponentUpdate"
},
{
"q3": "setState"
},
{
"q4": "componentUpdated"
}
]
var testData = [{
q1: "componentWillMount"
},
{
q2: "willComponentUpdate"
},
{
q3: " PropTypes"
},
{
q4: "componentDidMount"
}
];
var marks = 0;
var wrong = 0;
for (var k = 0; k < actualObject.length; k++) {
if (JSON.stringify(actualObject[k]) == JSON.stringify(testData[k])) {
marks++;
} else {
wrong++;
}
}
console.log(marks, wrong);
Actually i would like to take value from each key and compare it with the actualObject.
If I understand correctly something like this should work:
Object.entries(testData).forEach(function (entry) {
if (actualObject[entry[0]] === entry[1].trim()) {
//answers match
} else {
//answers don't match
}
});
If you need to compare regardless of case then change entry[1].trim() to entry[1].trim().toLowerCase().
EDIT:
Just to remind you that maybe you should add a check whether or not the values in the test data are null/undefined, if they are strings or not, etc.
var user_business_data =[
{
"user_id":"5db3e3b1",
"blog":{
"blog_id":"128c522e"
},
"business_units":[
{
"business_unit_id":"000396c9",
"viewing":101
},
{
"business_unit_id":"01821e44",
"viewing":102
},
{
"business_unit_id":"02cbcad5",
"viewing":103
}
]
}
]
I want to get all the "business_unit_id" and store in a varible. for this i need get all the "business_unit_id". so i tried to print all the id's with the below code but i was unable to print.
if (undefined !== user_business_data.business_units && user_business_data.business_units.length) {
for(var i=0;i<user_business_data.business_units.length;i++){
var key = user_business_data.business_units[i];
console.log("Key : "+key, "Values : "+user_business_data.business_units[key]);
}
} else {
console.log("Undefined value");
}
There always i am getting undefined value.
var user_business_data=[{"user_id":"5db3e3b1","blog":{"blog_id":"128c522e"},"business_units":[{"business_unit_id":"000396c9","viewing":101},{"business_unit_id":"01821e44","viewing":102},{"business_unit_id":"02cbcad5","viewing":103}]}]
var unit_ids = [];
user_business_data.forEach(function(user) {
user.business_units.forEach(function(business) {
unit_ids.push(business.business_unit_id);
});
});
console.log(unit_ids);
user_business_data is an array, not an object, so you either need to loop through it or read a specific index from it.
Also, key in your code will be an object (a single business unit object), so you can't print it directly - instead you need to fetch a specific property within the object.
Here's a simple demo reading the first key from the outer array and then listing all the specific properties from the business units. The code can be simplified further potentially, but this illustrates the point:
var user_business_data =
[{
"user_id": "5db3e3b1",
"blog": {
"blog_id": "128c522e"
},
"business_units": [{
"business_unit_id": "000396c9",
"viewing": 101
},
{
"business_unit_id": "01821e44",
"viewing": 102
},
{
"business_unit_id": "02cbcad5",
"viewing": 103
}
]
}]
if (undefined !== user_business_data[0].business_units && user_business_data[0].business_units.length) {
for (var i = 0; i < user_business_data[0].business_units.length; i++) {
var key = user_business_data[0].business_units[i].business_unit_id;
console.log("Key : " + key, "Values : " + user_business_data[0].business_units[i].viewing);
}
} else {
console.log("Undefined value");
}
I suggest you get clear in your head the difference between arrays, objects and properties in JSON / JS objects, and then this kind of thing will become trivial.
user_business_data is an array and not an object.If you want to access any object from an array you have to specify the index as of which position you are referring.Therefore in your example change it to following to work:
if (undefined !== user_business_data[0].business_units && user_business_data[0].business_units.length) {
for(var i=0;i<user_business_data[0].business_units.length;i++){
var key = user_business_data[0].business_units[i]. business_unit_id;
console.log("Key : "+key, "Values : "+user_business_data[0].business_units[key]);
}
} else {
console.log("Undefined value");
}
It's because user_business_data is an array, not an object yet you access it like user_business_data.business_units instead of user_business_data[0].business_units
var user_business_data = [{"user_id": "5db3e3b1","blog": {"blog_id": "128c522e"}, "business_units": [{"business_unit_id": "000396c9","viewing": 101}, {"business_unit_id": "01821e44","viewing": 102},{"business_unit_id": "02cbcad5","viewing": 103}]}];
// Both methods give the same result, but the second checks for null values.
var ids1 = user_business_data[0].business_units.map(x => x.business_unit_id)
console.log('Method 1:', ids1);
// The && check for null values, kinda like an if statement.
var data = user_business_data.length && user_business_data[0]
var units = data && data.business_units
var ids2 = units && units.length && units.map(x => x.business_unit_id)
console.log('Method 2:', ids2)
If you want to print only the business_unit_ids then you can do as follows:
var user_business_data =
[
{
"user_id": "5db3e3b1",
"blog": {
"blog_id": "128c522e"
},
"business_units": [
{
"business_unit_id": "000396c9",
"viewing": 101
},
{
"business_unit_id": "01821e44",
"viewing": 102
},
{
"business_unit_id": "02cbcad5",
"viewing": 103
}
]
}
]
for(var i=0;i<user_business_data[0]["business_units"].length;i++){
console.log(user_business_data[0]["business_units"][i].business_unit_id)
}
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);
}
}
I have some json : data.
I have a string build that looks like this:
sections.1.subsections.0.items.0.citation.paragraph
What I need to do is manipulate that string to be able to access that value in data. So turn it into something usable:
data['sections'][1]['subsections'][0]['items'][0]['citation']['paragraph']
And then use it to change that value in data. So:
data['sections'][1]['subsections'][0]['items'][0]['citation']['paragraph'] = 'new value'
I can split the original string on the . and I think that gets me somewhere but I'm not at all sure how to then re-use the parts to allow me access to that value in data.
Thanks!
I'm still not quite sure why you're handling the JSON in this fashion but if it has to be done this way, then you'll need to use recursion to access the data. Assuming I mapped your object correctly, the example below should provide you with a method for doing this:
var data = {
sections: [
{
subsections: []
},
{
subsections: [
{
items: [
{
citation: {
paragraph: "Citation by Warlock"
}
}
]
}
]
}
]
};
var string = "sections.1.subsections.0.items.0.citation.paragraph",
parts = string.split('.');
function getValue(tree, index) {
if(index < (parts.length - 1)) {
return getValue(tree[parts[index]], index + 1);
} else {
return tree[parts[index]];
}
}
function setValue(tree, index, newValue) {
if(index < (parts.length - 1)) {
setValue(tree[parts[index]], index + 1, newValue);
} else {
tree[parts[index]] = newValue;
}
}
alert(getValue(data, 0));
setValue(data, 0, "New Citation By Warlock");
alert(getValue(data, 0));
The idea is that the getValue(...); function steps one layer deep into your JSON and then recursively calls itself. This allows the data to be accessed one step at a time until the last part is retrieved. The value is then returned via the recursion in all the previous function calls.
The same idea is true for setting the value. The setValue(...); function steps into the JSON one layer at a time passing the new value to set until it's reached the last nested layer. The value is then set for the specified property.
EDIT:
A better implementation would be to pass the parts array into the getValue(...); and setValue(...); function to eliminate external dependencies. Then, within the function shift the array's data values to step through the nested layers. This eliminates the need for index tracking based on the original array's values:
var data = {
sections: [
{
subsections: []
},
{
subsections: [
{
items: [
{
citation: {
paragraph: "Citation by Warlock"
}
}
]
}
]
}
]
};
var string = "sections.1.subsections.0.items.0.citation.paragraph",
parts = string.split('.');
function getValue(temp, tree) {
if(temp.length > 1) {
tree = tree[temp[0]];
temp.shift();
return getValue(temp, tree);
} else {
return tree[temp[0]];
}
}
function setValue(temp, tree, newValue) {
if(temp.length > 1) {
tree = tree[temp[0]];
temp.shift();
setValue(temp, tree, newValue);
} else {
tree[temp[0]] = newValue;
}
}
alert(getValue(parts, data));
setValue(parts, data, "New Citation By Warlock");
alert(getValue(parts, data));