javascript access objects in an array [duplicate] - javascript

This question already has answers here:
Find object by id in an array of JavaScript objects
(36 answers)
Closed 8 years ago.
If I have something like this:
var quiz = [{
"questionID": "KC2Q4",
"correctAnswer": "KC2Q4a"
},{
"questionID": "KC2Q5",
"correctAnswer": "KC2Q5b"
}];
and have a variable that we can call "question" that has a value of a string like KC2Q4. How do I return the "correctAnswer" for the "questionID" that matches the variable "question" in a new variable "answer"?

You essentially want to iterate over your array, checking each object for the proper questionID. When you find that object, return the correctAnswer property of that object.
var question = "KC2Q4";
for( var i=0; i<quiz.length; i++ ){
if( quiz[i].questionID === question ){
return quiz[i].correctAnswer;
}
}

You should use Array.prototype.filter function (note filter() is a ECMA-Script 5.x native function: you don't need third-party libraries or frameworks!!):
var correctAnswer = "KC2Q4a";
// "filter" is like a "where". It iterates each object in your array
// and returns ones that fit the given condition as a closure:
var answersFound = quiz.filter(function(question) {
return question.correctAnswer == correctAnswer;
});
// You could verify if length > 0, but you want to be sure that
// there's only a single match for a given correct answer, because I feel
// that "correctAnswer" is like an unique id...
if(answersFound.length == 1) {
// Since there's a found answer to given "correctAnswer",
// you get the single result (i.e. the question object):
var answer = answersFound[0];
}
If you find above checking useless (in my case, I would call it defensive programming), you may retrieve the question object directly this way:
// Without the checking done in the other code listing, you've two risks:
// a. "quiz" could contain no question objects and the filter will return zero results
// meaning that getting first result array index will throw an error!
//
// b. "quiz" could contain question objects but what you're looking for isn't
// present in the so-called array. Error too!
var answer = quiz.filter(function(question) {
return question.correctAnswer == correctAnswer;
})[0];

Related

JavaScript insert a new property to inline object only if condition is met [duplicate]

This question already has answers here:
In JavaScript, how to conditionally add a member to an object?
(29 answers)
Closed 2 years ago.
I'm aware with ES6 JavaScript object you can dynamically declare variables as object keys, using [], for example:
{[2 + 2]: "four!"}
gives the output {"4": "four!"}
the question is, can a similar method be done in order to add an entire property, through variables etc., inline? Meaning, like suppose I have the following test object:
var myObj = {
someProp: 2,
someOtherProp: 3 //only add this prop if a condition is met
}
is there anything I can write in the inline object for someOtherProp, to only have it be added to the object, if a certain condition is met? So for example (pseudocode), something like this
var myObj = {
someProp: 2,
[someBool ? null : "someOtherProp: 3"] //only add this prop if a condition is met
}
would give the ouput (considering someBool is true), like the above, but if someBool is false, it would give me
var myObj = {
someProp: 2
}
??
I'm aware I can simply add a property (or delete one) to (/from) the object later, using the [] indexer, like
someBool && (myObj["someOtherProp"] = 3)
as well as make some kind of helper function for this,
but I was wondering if there was a way to do it using the inline-object notation?
You could spread an object with a conditional operator.
{} is a neutral value.
var myObj = {
someProp: 2,
...(someBool ? {} : { someOtherProp: 3 })
}

Going through a object with a variable [duplicate]

This question already has answers here:
JavaScript object: access variable property by name as string [duplicate]
(3 answers)
Closed 6 years ago.
I guess I didnt really know how to ask this question for me to find an answer.
So I have three variables that are going to make this function do what it has to
function gatherDataForGeographic(ele) {
var $this = $(ele)
var $main_title = $this.find('.options-title'),
$option = $this.find('.option');
var arr = []
var reportAreas = reportManager.getReportAreasObject();
$option.each(function () {
var $this = $(this)
var $checkbox = $this.find('.checkbox');
var type = $this.data('type'),
index = $this.data('index');
if ($checkbox.hasClass('checkbox--checked')) {
console.log(reportAreas.type)
} else {
return true;
}
})
return arr;
}
//this will return an object that I need to index
var reportAreas = reportManager.getReportAreasObject();
//this will get the a key that i need from the object
var type = $this.data('type');
//this will give me the index I need to grab
var index = $this.data('index');
So what I am trying to do is go through the object based on the type(or key) from the option selected by a user
The problem...
It is looking for reportArea.type[index] and is not recognizing it as a variable and I keep getting undefined because .type does not exist.
Is there a way for it to see that type is a variable and not a key?
You can use dynamic properties in JS using the bracket syntax, not the dot syntax:
reportAreas[type]
That will resolve to reportAreas['whateverString'] and is equivalent to reportAreas.whateverString- reportAreas.type however, is a literal check for type property.
reportArea[type][index]
JavaScript objects are just key-value pairs and the dot syntax is just syntactic sugar for the array notation.
object['a']
and
object.a
Are the same thing, basically.

How to Find Out if a Property in an Object Exists [duplicate]

This question already has answers here:
Test for existence of nested JavaScript object key
(64 answers)
Closed 7 years ago.
Does anyone know a clean way to find out if an object property exists? Here is my example:
var test = {
a : 'west',
b : {
a : 'rest'
},
d : {
a : 'pest'
}
};
// I want to access 'a' in 'c'
typeof test.c.a; // fails!
typeof it seems can't get past the fact that 'c' doesn't exist to check if 'a' exists inside it (I've also tried jQuery.type() which also fails in the same way - I would have thought it would have error checking inside that function).
In this example of course I could simply check if 'c' exists first but in my real situation I have a large and deep object and I need to dynamically retrieve data from any potential location so it would be nice if there were a ready-made solution which didn't necessitate having to use a try-catch.
Thanks in advance!
I can't vouch for any existing functionality in any js framework for finding nested properties, but you can certainly roll your own.
hasOwnProperty is part of the ECMA script standard.
if(test.hasOwnProperty("c"))
{
console.log("test.c = " + test.c);
}
If you are looking to find deeply nested properties, then you could roll your own function to check if the nested property exists, and if so, return it.
function hasNestedProperty(testObject, properties)
{
var maxDepth = properties.length;
var i, hasProperty = false;
var currObj = testObject;
while(hasProperty && i < maxDepth)
{
if(currObj.hasOwnProperty(properties[i])
{
currObj = currObj[properties[i]]);
i ++;
}
else
{
hasProperty = false;
}
}
return hasProperty;
}

Something other than looping through array? [duplicate]

This question already has answers here:
How do I check if an array includes a value in JavaScript?
(60 answers)
Closed 8 years ago.
My question is, how can I make the program do something if some variable is equal to any element in an array? Is there any other simpler way than just looping through the entire array?
For example: Suppose there is a variable, line = 0; and an array, characters = [1,2,3,4];
So, what I want to do is that, if the variable "line", changes to any of the four elements in the array "characters" (i.e. 1,2,3,4), then the program needs to do something specific.
(The array can be way bigger than that and the elements in the array might be created during the program not beforehand.)
if (characters.indexOf(line) >= 0) {
// It's in the array
}
Use Array.indexOf to see if an element in in an array. If it returns -1 then the element is not in the array.
var line = 0;
var chars = [1,2,3,4]
if (chars.indexOf(line) === -1) {
console.log("Not there.");
} else {
console.log("Array contains " + "'" + line + "'");
}
It's not very clear exactly what you are trying to do, but one idea would be to use an object rather than an array so you can do the look up faster. If your "something specific" is a function, you could even have an object where that "something specific" is a function in your object. For example:
var characters = {
1: function() { alert("hey there"); },
2: function() { return 1 + 1; },
3: function() { destroyTheWorld(); }
};
Then you could do something like this:
line = 1;
characters[line]();
Use indexOf() to search inside an array
http://www.w3schools.com/jsref/jsref_indexof_array.asp
it will return the position of the object inside the array, so it means that is there, just need a comprobation for that maybe like this:
if(position = characters.indexOf(line)){
//value contains the searched item...
value = characters[position];
}else{
//not there
}

How do you access an object within an object from an argument in Javascript? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Accessing nested JavaScript objects with string key
I have the function
function _get(name) {
return plugin._optionsObj[name] !== undefined ?
plugin._optionsObj[name] : plugin._defaults[name];
}
I would like to be able to have objects inside of my _defaults object, but then I don't know how to retrieve them but using just one set of square brackets.
i.e.
plugin._defaults = {
val1: 1,
val2: 2,
obj1: {
someVal: 3
}
}
Is it possible to access 'someVal' from the function I have above? I tried passing 'obj1.someVal' for the argument and it didn't work. Ideas?
Edit: I have found a solution and I posted it below as an answer. I've written a very nice little function to do go through the nested values with a string and I didn't have to change my function much to implement it. I hope this helps anyone in a similar situation.
I suspect that you won't always have a one-level nested object to access, so the cleaner way to do this is to use a function that traverses an object based on a string path. Here's one that is coded as a mixin for Underscore. You can then just use it like so:
_.deep(plugin._defaults, 'obj1.someVal');
This thread also has some non-Underscore alternatives.
Pass multiple arguments, and iterate over the arguments object.
function _get(/* name1, name2, namen */) {
var item = plugin._optionsObj,
defItem = plugin._defaults;
for (var i = 0; i < arguments.length; i++) {
item = item[arguments[i]];
defItem = defItem[arguments[i]];
if (item == null || defItem == null)
break;
}
return item == null ? defItem : item;
}
var opt = _get("obj1", "someVal")
I found a solution for this problem, at least one that will accommodate myself, and I'd like to share it in case it can help someone else with this problem. My biggest difficulty is that I did not know the depth of the nested value so I wanted to find a solution that would work for deeply nested objects and without requiring to redesign anything.
/* Retrieve the nested object value by using a string.
The string should be formatted by separating the properties with a period.
#param obj object to pass to the function
propertyStr string containing properties separated by periods
#return nested object value. Note: may also return an object */
function _nestedObjVal(obj, propertyStr) {
var properties = propertyStr.split('.');
if (properties.length > 1) {
var otherProperties = propertyStr.slice(properties[0].length+1); //separate the other properties
return _nestedObjVal(obj[properties[0]], otherProperties); //continue until there are no more periods in the string
} else {
return obj[propertyStr];
}
}
function _get(name) {
if (name.indexOf('.') !== -1) {
//name contains nested object
var userDefined = _nestedObjVal(plugin._optionsObj, name);
return userDefined !== undefined ? userDefined : _nestedObjVal(plugin._defaults, name);
} else {
return plugin._optionsObj[name] !== undefined ?
plugin._optionsObj[name] : plugin._defaults[name];
}
}
To retrieve objects inside of your _defaults object you'll need to improve your _get function.
For example you may pass an array of strings (each string representing a propery name) to _get to allow access to deeply nested objects.

Categories