I wanted to check if the an object has a property of something and its value is equal to a certain value.
var test = [{name : "joey", age: 15}, {name: "hell", age: 12}]
There you go, an array of objects, now I wanted to search inside the object and return true if the object contains what I wanted.
I tried to do it like this:
Object.prototype.inObject = function(key, value) {
if (this.hasOwnProperty(key) && this[key] === value) {
return true
};
return false;
};
This works, but not in an array. How do I do that?
Use the some Array method to test your function for each value of the array:
function hasValue(obj, key, value) {
return obj.hasOwnProperty(key) && obj[key] === value;
}
var test = [{name : "joey", age: 15}, {name: "hell", age: 12}]
console.log(test.some(function(boy) { return hasValue(boy, "age", 12); }));
// => true - there is a twelve-year-old boy in the array
Btw, don't extend Object.prototype.
-- for the property --
if(prop in Obj)
//or
Obj.hasOwnProperty(prop)
-- for the value ---
Using "Object.prototype.hasValue = ..." will be FATAL for js but Object.defineProperty let you define properties with enumerable:false (default)
Object.defineProperty(Object.prototype,"hasValue",{
value : function (obj){
var $=this;
for( prop in $ ){
if( $[prop] === obj ) return prop;
}
return false;
}
});
just for experiment test if a NodeList has an Element
var NL=document.QuerySelectorAll("[atr_name]"),
EL= document.getElementById("an_id");
console.log( NL.hasValue(EL) )
// if false then #an_id has not atr_name
For array, of course you have to browse that array with for
for(var i = 0 ; i < yourArray.length; i++){
if(yourArray[i].hasOwnProperty("name") && yourArray[i].name === "yourValue") {
//process if true
}
}
Typically you'll use something like Object.first:
// search for key "foo" with value "bar"
var found = !!Object.first(test, function (obj) {
return obj.hasOwnProperty("foo") && obj.foo === "bar";
});
Assuming that Object.first will return some falsy value when it doesn't find a match.
Object.first is not a native function but check on of the popular frameworks, they're bound to have one.
Here is another solution for checking if the object has the property but the value of property is not set. Maybe the property value has 0, null or an empty string.
array.forEach(function(e){
if(e.hasOwnProperty(property) && Boolean(e[property])){
//do something
}
else{
//do something else
}
});
Boolean() is the trick here.
Related
Alright then implement the objContains function: must search inside a nested object for a pair {key: value} specific. Both the object and the property name and its value will be received by parameter.
In the event that it finds the indicated value at any level of the object, it must return true, otherwise return false.
Ex:
const user = {
id: 6,
email: 'homero#maxpower.com',
Personal info: {
name: 'Homer Simpson',
address: {
street: 'Avenue AlwaysLive',
number: 742,
neighborhood: 'Springfield',
state: 'Massachusetts'
}
}
}
Case that returns true -> objContains (user, "neighborhood", "Springfield");
Case that returns false -> objContains (user, "employment", "Employee in nuclear plant");
Hint: use typeof to determine if the value of a property is an object to apply
there the recursion
this is what i've try
var objContains = function (obj, prop, value) {
object var = prop.value
if (typeof prop.value === obj) {
var current = this.value;
objContains (object, prop, current)
} else if (this.prop === prop && prop.value === value) {
return true;
} else {
return false;
}
}
AssertionError: expected false to equal true
32 | }
33 | it ('It should return true if it finds the property and its correct value', fun
ction () {
> 34 | expect (objContains (user, "neighborhood", "Springfield")). to.equal (true);
35 | });
36 | it ('Should return false if the property is NOT found', function () {
37 | expect (objContains (user, "employment", "Employee at nuclear power plant")). to.equal (
false);
There are a couple of problems:
typeof prop.value checks the type of the property with the literal name value on whatever prop is. You've described prop as the name of an object property, so it doesn't make sense to try to look for value on it. You want to look on obj, not prop, using the syntax described in this question's answers. I don't think it's writing it for you to say that that looks like this: if (obj[prop] === value)
If you don't find the property with that value on obj, you should be looking through the other properties on obj and, if any of them refer to objects, calling your function with the object they refer to (and prop and value) and, if the function returns true, return true. Looping through the properties on the object is covered by this question's answers.
So the general form of a solution would be:
See if obj has a property whose name is the value of prop that matches the value of value. If so, return true.
If not, loop through obj's other properties and check the type of their values; for each one that's an object (typeof is "object" and the value isn't null), call your function again with that property value, prop, and value. If it returns true, return true. If not, keep looping.
I'm purposefully just giving an indication of where to go, rather than writing the code, because this seems like an assignment we should help you with rather than doing for you.
I loop through each key in object... if the the key refers to an object itself then recursively call... else check to see if that's the key we're looking for and if so check its value... using the |= operator makes it easy to not worry about results of individual calls... we just care if the conditions are true ANYWHERE in the tree..
const user = {
id: 6,
email: 'homero#maxpower.com',
"Personal info": {
name: 'Homer Simpson',
address: {
street: 'Avenue AlwaysLive',
number: 742,
neighborhood: 'Springfield',
state: 'Massachusetts'
}
}
}
var objContains = function(obj, prop, value) {
var returnValue = false;
var keyArray = Object.keys(obj);
keyArray.forEach(property => {
if (typeof(obj[property]) == 'object') {
returnValue |= objContains(obj[property], prop, value);
} else if (property == prop) {
returnValue |= obj[property] == value;
}
});
return !!returnValue;
}
console.log(objContains(user, 'neighborhood', 'Springfield'));
ive got an object:
var car = {
company: "Honda",
year: "2011",
Model: "Brio"
}
I was wondering if there exists an inherited method (is that the right phrase?) to check if a value exists inside a given object, somewhat like x.hasOwnProperty, or if (x in car). Or, should I write my own.
I've done a few google searches, but they all either lead to hasOwnProperty or to check if a value exists inside an array.
Editing to please all the people in the comments:
There are two use cases i could think of where this would be useful:
checking for undefined keys and reporting which one
if (!car.isInvalid(car, undefined))
validCarsArray.push (car);
Checking if a general user input exists in an object
var text = searchBox.input;
validCarArrays.forEach (function (car) {
if (car.hasOwnValue(car, text)) {
displayToUserAsResult (car);
}
});
Let's say we start with
const obj = {foo : "bar"};
Check for a value:
const hasValue = Object.values(obj).includes("bar");
Check for a property:
// NOTE: Requires obj.toString() if key is a number
const hasProperty = Object.keys(obj).includes("foo");
Multi-level value:
function hasValueDeep(json, findValue) {
const values = Object.values(json);
let hasValue = values.includes(findValue);
values.forEach(function(value) {
if (typeof value === "object") {
hasValue = hasValue || hasValueDeep(value, findValue);
}
})
return hasValue;
}
Multi-level property:
function hasPropertyDeep(json, findProperty) {
const keys = Object.keys(json);
let hasProperty = keys.includes((findProperty).toString());
keys.forEach(function(key) {
const value = json[key];
if (typeof value === "object") {
hasProperty = hasProperty || hasPropertyDeep(value, findProperty);
}
})
return hasProperty;
}
No, there is no built in method to search for a value on an object.
The only way to do so is to iterate over all the keys of the object and check each value. Using techniques that would work even in old browsers, you can do this:
function findValue(o, value) {
for (var prop in o) {
if (o.hasOwnProperty(prop) && o[prop] === value) {
return prop;
}
}
return null;
}
findValue(car, "2011"); // will return "year"
findValue(car, "2012"); // will return null
Note: This will return the first property that contains the search value even though there could be more than one property that matched. At the cost of efficiency, you could return an array of all properties that contain the desired value.
Note: This uses the extra .hasOwnProperty() check as a safeguard against any code that adds enumerable properties to Object.prototype. If there is no such code and you're sure there never will be, then the .hasOwnProperty() check can be eliminated.
There is no built-in function but it can be done using Object.keys() and [].some():
function hasValue(obj, value) {
return Object.keys(obj).some((key) => obj[key] == value);
}
var car = {
company: "Honda",
year: "2011",
Model: "Brio"
}
snippet.log('car has Honda: ' + hasValue(car, 'Honda'));
snippet.log('car has NotHonda: ' + hasValue(car, 'NotHonda'));
<script src="https://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
This function uses Object.keys() and returns an array with the keys for the object which has the given value.
The Object.keys() method returns an array of a given object's own enumerable properties, in the same order as that provided by a for ... in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
var car = {
company: "Honda",
year: "2011",
Model: "Brio"
};
function getKeysWithValue(v, o) {
return Object.keys(o).filter(function (k) {
return o[k] === v;
});
}
document.write('<pre>' + JSON.stringify(getKeysWithValue('Honda', car), 0, 4) + '</pre>');
I used this function, to check wether or not array2 contains a common value with array1.
const array1 = ['a','b','c','x'];
const array2 = ['z','y','x'];
function ContainsCommonItem3(arr1, arr2){
return arr1.some(item => arr2.includes(item));
}
I've got a object like this:
{"status":200,
"success":true,
"result": [ {"Description":"", "Year":"", "Price/STK":"", "Main Cat":"Fruits"} ]
}
I have distinct lists I need to use, and the Price key can be: Price/STK, Price/Box, Price/Btl or Price.
I know I can get the value using, for example, data.result['Price/STK'], but I don't want to check every key, I'd like to search for the price and just use.
How would I determine if a word ('Price*', for example) is part of a key and get that value?
There's no built in way to do this, you have to iterate and check each key.
You could just create a convenient function :
function matchKey(objectToSearch, keyToFind) {
for (var k in objectToSearch) {
if ( k.toLowerCase().indexOf(keyToFind.toLowerCase()) !== -1)
return objectToSearch[k];
}
return null;
}
matchKey({year : 2015, "Price/STK" : "value"}, "price"); // returns "value"
FIDDLE
You could solve this problem easily using lodash (or underscore)
_.findKey(obj, function(key) { return _.startsWith(key, 'Price')})
This finds the first key that starts with price.
You can get the property names of an object using Object.keys, and then use indexOf to search for a value, but it does an exact match and doesn't take a regular expression as an argument.
So you have to loop over all the property names until you find the one you want. There are built–in iterators to help:
var obj = {"status":200,
"success":true,
"result": [ {"Description":"desc",
"Year":"yr",
"Price/STK":"price/stk",
"Main Cat":"Fruits"}
]
};
function getValueLike(obj, prop){
var re = new RegExp('^' + prop);
var value;
Object.keys(obj).some(function(prop) {
if (re.test(prop)) {
value = obj[prop];
return true;
}
});
return value;
}
document.write(getValueLike(obj.result[0], 'Price')); // price/stk
A version that uses indexOf on the property name might be faster and is a little less code:
function getValueLike(obj, prop){
var value;
Object.keys(obj).some(function(key) {
if (key.indexOf(prop) == 0) {
value = obj[key];
return true;
}
});
return value;
}
which can be reduced to:
function getValueLike(obj, prop, value){
Object.keys(obj).some(function(key) {return key.indexOf(prop) == 0 && ((value = obj[key]) || true)});
return value;
}
which also allows a default value to be passed to value, but it's a little too obfuscated for me.
Using an arrow function:
function getValueLike(obj, prop, value){
Object.keys(obj).some(key => key.indexOf(prop) == 0 && ((value = obj[key]) || true));
return value;
}
Filter the set of keys on the result array's object for "Price", and then return the value associated with that. I made a function for it as an example.
function selectPrice(obj){
return obj.result[0][
Object.keys(obj.result[0]).filter(function(el){
return el.indexOf("Price") > -1
})[0]
]
}
var data = {"status":200,
"success":true,
"result": [ {"Description":"", "Year":"", "Price/STK":"6", "Main Cat":"Fruits"} ]
};
document.write(selectPrice(data));
I have the following object:
var text = { 'one' : 1, 'two' : 2, 'three' : 3};
I want to write the key 'one' with console.log(). How can I do it?
try:
var text = { 'one' : 1, 'two' : 2, 'three' : 3};
for (var i in text){
console.log(i);
}
You need to use the keys() function, as epoch pointed out in the comment section.
For example :
console.log(Object.keys(text));
Can print one two three; If you want to be certain about your order, you'll have to use an array instead of an object, as properties in objects are not ordered.
Be careful, in older browers you'll have to define your own fucntion of keys, as explained in the doc i linked above, like so :
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
Your question is kind of vague.
What exactly is it that you are trying to achieve?
Do you just want to log the first prop in your obj?
If so, that would not be a good idea because the order of properties in an object is not guaranteed. The order might even change over time, depending on what happens to the object.
You could in fact use the Object.keys() method, which would do a for in on all enumerable properties of the object, but this would give you all properties and since you asked for a specific property to be logged to the console, this leads me to the conclusion that you probably are more interested in how to check for the existence of a property.
To make a long story short, if you really want to log a specific property you could just do
(text.hasOwnProperty('one')) ? console.log('one') : console.log('"one" does not exists');
How can i validate an object of arrays that's passed as a parameter to my jQuery plugin to make sure it contains specific members/names?
For example, I want to validate if this object below has 'name', 'ID' & 'Location', all three members, which in this case should be true.
var arr = [{
name: 'Johny',
ID: 1,
Location: 'USA'
}, {
name: 'Mike',
ID: 4,
Location: 'CAN'
}];
Thanks in advance.
Johny
You can use Array.prototype.every method to test that every object in array conforms necessary keys rules:
var valid = arr.every(function(obj) {
var keys = Object.keys(obj);
return keys.length === 3 && 'name' in obj && 'ID' in obj && 'Location' in obj;
});
You should really make an effort (and show what you've tried and why it didn't work).
There are many ways to do what you're asking. Here is one:
arr.forEach(function(object) {
if (!object.name || !object.ID || !object.Location) {
throw Error("Missing properties");
}
});
You could check each property individually and throw an error that said what property (or properties) was missing if that's desired.
You can check each property exists by using Object.hasOwnProperty() like so:
function isValid(arr){
// If arr is an array
if( arr && arr.constructor === Array){
// For each item
for(var i=0, l=arr.length; i<l; i++){
var item = arr[i];
if( !typeof item !== 'object'
|| !item.hasOwnProperty('name')
|| !item.hasOwnProperty('ID')
|| !item.hasOwnProperty('Location')
// This is to check if it has *exactly* those 3 properties and no more
|| Object.keys(arr).length != 3){
return false;
}
}
return true;
}
return false;
}