Object get the value by a key - javascript

I'm kinda stuck with an issue. This is the response for my AJAX call.
var test = [
{
"analytics.feature": "false"
},
{
"demo": "true"
},
{
"analytics.demo": "false"
}
]
Now I want to check if analytics.demo is enabled or disabled.
Can I use _.find?
_.find(test, {analytics.demo}); //returns error
I just want to do this
if(analytics.demo) {
//Do something
}
How do I do that? Can someone help?
Instead of iterating objects and comparing, can I use underscorejs/jQuery to get the exact value for a key?

const options = Object.assign(...test)
console.log(options) // { "analytics.feature": "false", demo: "true", "analytics.demo": "false" }
if (options['analytics.demo'] === 'true') {
// ...
}
(Note that this uses ES6. For ES5 use var options = Object.assign.apply(object, test) instead, and you also need to polyfill Object.assign.)
This uses Object.assign() with the spread operator to merge the objects into one, then get the "analytics.demo" option from the new single object. It has to be accessed using bracket notation because the key has a dot in. It is compared to the string true because "false" (string) is true but false (boolean) is false.
There is more information on SO about flattening arrays and converting strings to booleans.
PS is there any way you can get the Ajax call to use proper booleans instead of strings? It would be easier to work with.

You can check if any of the items in the array matches a certain condition like so:
var isDemoEnabled = test.some(function (item) {
return item['analytics.demo'] === 'true';
});
if (isDemoEnabled) {
// Do something
}
If the values were boolean, you could remove === 'true'

Assuming you're using underscore, check out the documentation regarding find:
http://underscorejs.org/#find
Find runs a predicate function for every element in an array and returns a new array that contains every value where the predicate function returned true.
In this case we want to find if the element has a field analytics.demo
To do this we can use the underscore function _.has:
http://underscorejs.org/#has
all in all:
var result = _.find(test, function(elem) {
return _.has(elem, "analytics.demo");
}
);

You could iterate over and check if the key is given and return then the result.
function getKeyValue(array, key) {
var value;
array.some(function (a) {
if (key in a) {
value = a[key];
return true;
}
});
return value;
}
var test = [{ "analytics.feature": "false" }, { "demo": "true" }, { "analytics.demo": "false" }]
console.log(getKeyValue(test, 'analytics.demo')); // 'false' a string with this value

Related

Javascript search an array for a value starting with a certain value

I am looking for a way to search an array to see if a value is present that starts with the search term.
const array1 = ['abc','xyz'];
So a search for 'abcd' would return true on the above.
I have been playing about with includes, but that only seems to check the full value.
Also, startsWith I dont think will work as I believe that checks a string and not values in an array??
You can use the find() function which allows you to pass a custom function in parameter that will be tested on each value. This way you can use startsWith() on each value of the array as you intended to do.
Example:
const array1 = ['abc','xyz'];
function findStartWith(arg) {
return array1.find(value => {
return arg.startsWith(value);
});
}
console.log(findStartWith("hello")); // undefined
console.log(findStartWith("abcd")); // abc
console.log(findStartWith("xyzz")); // xyz
If you want to return true or false instead of the value, you can check if the returned value is different from undefined.
function findStartWith(arg) {
return !!array1.find(value => {
return arg.startsWith(value);
}) !== undefined;
}
The same snippet with a boolean:
const array1 = ['abc','xyz'];
function findStartWith(arg) {
return array1.find(value => {
return arg.startsWith(value);
}) !== undefined;
}
console.log(findStartWith("hello")); // false
console.log(findStartWith("abcd")); // true
console.log(findStartWith("xyzz")); // true

Check arraylist property if it true for all objects

I have the following Javascript array of objects ,I need to check output property if it true for all objects , if output true for all object return true else return false,Can anyone help me to implement that?
var array=[{"id":100,"output":true},{"id":200,"output":true}]
updates
I have try this code but it execute print if just one output is true not all output
function check(){
var data=[{"id":100,"output":false},{"id":200,"output":true}]
data.every(function (e) {
if(e.checked===true){
console.log("print something")
}
});
}
what is the wrong in code?
You can use Array.every() to tests whether all elements in the array pass the test implemented by the provided function
var array = [{"id":100,"output":true},{"id":200,"output":true}]
var istrue = array.every( obj => obj.output === true );
console.log(istrue)
In ES5
array.every( function(obj) { return obj.output === true });
Note that this does strict checking against the boolean true, not just any truthy value

How to rewrite the following function so it doesn't use for loops?

The following function takes an object, loops through each value and returns false if the object or its children have an empty or undefined property web. Otherwise, it returns true:
hasNoCategories (object) {
for (let key in object) {
const value = object[key]
for (let i = 0; i < value.length; i++) {
const item = value[i]
if (item.web !== undefined && item.web !== '') return false
}
if (key === 'web' && value !== '') {
return false
}
}
return true
},
Example input:
{
"livingroom": [],
"garage": [],
"outdoors": [],
"other": [],
"id": "ZI4hteKxgr",
"name": "Cuiti",
"description": "",
"user": "",
"date": "2016/5/13",
}
How to rewrite this function without using for loops?
I'm not 100% sure what you expect the code to do, because your existing code and your description differ.
Your description is, rephrased, that this function checks whether object.web or any object.XXX.web are undefined. Your code however assumes that all members are arrays and checks whether object.web or object.XXX[YYY].web are undefined. (Note that it also doesn't do it correctly and accesses .length even though the member in question might be undefined.)
Since I'm not sure which of those is right, I'm providing two answers.
Functionality as per your textual description:
function hasNoCategories(object) {
if(!object.web) return false;
return Object.keys(object).every(function(key) {
if(typeof object[key] !== 'object') return true;
return !!object[key].web;
});
}
Functionality as per your existing code: (but with the length property access fixed)
function hasNoCategories(object) {
if(!object.web) return false;
return Object.keys(object).every(function(key) {
if(!Array.isArray(object[key])) return true;
return object[key].every(function(el) {
if(typeof object[key] !== 'object') return true;
return !!el.web;
});
});
}
To understand how this works, check out the documentation on Object.keys (which returns an array with the names of all keys in your object) and Array.prototype.every (which runs a callback function for every element in an array and returns true only if the callback returned true for every element).
Note that I'm assuming that your "empty or undefined" should reject all kinds of falsy values including null and the number (not string) zero. If not, then all the checks like if(!something) and return !!something would need to be changed to if(typeof something === "undefined" || something === '') and return typeof something !== "undefined" && something !== '', respectively.
Side note to prevent nitpicking: Of course there are still loops going on. But it was specifically asked "without for loop" and there is no for in this code.
I assume this is what you are looking for:
var hasNoCategories = function(object) {
if (!object.web) {
return false;
}
for (let key in object) {
var value = object[key];
if (!value.web) {
return false;
}
}
return true;
};
I got rid of 1 loop. But this cannot be done without loops because you have to loop over all children. You can hide this loop inside some another function but you cannot get rid of it.
If you really don't want to use loops (I don't know why), one of your options is to serialize the object and phrase the string for the word "web".
var s = JSON.stringify(object);
var webIndex = s.indexOf('web');
Now perform some checks around this index to ascertain if that has the value 'undefined' or ''. Please keep in mind that the word "web" can match as a part of another property name too. So, you need to include this possibility too to your checks.

How to check if an object is "deep empty"?

i have a method that returns an object that contains 4 objects:
function getFiles() {
var documents = {};
documents.files1ToBeCompleted = DocumentsService.getFiles1Uncompleted();
documents.files2ToBeCompleted = DocumentsService.getFiles2Uncompleted();
documents.files3ToBeCompleted = DocumentsService.getFiles3Uncompleted();
documents.files4ToBeCompleted = DocumentsService.getFiles4Uncompleted();
return documents;
}
I'm trying to use Underscore function ._isEmpty to verify if the object is empty, i mean the case in which i get an object with empty sub-objects.
But even all its 4 objects are empty, it is not empty because it contains 4 items.
Do you know any way to check if an object is "deep empty"?
Here's what worked for me. It is recursive and takes care of all nested objects (uses lodash).
function isEmptyDeep(obj) {
if(isObject(obj)) {
if(Object.keys(obj).length === 0) return true
return every(map(obj, v => isEmptyDeep(v)))
} else if(isString(obj)) {
return !obj.length
}
return false
}
It first checks if there are no keys, and returns true in that case.
Then it checks the keys and runs isEmptyDeep on each. If the value is an object (or array), it will continue recursion.
If there's an empty array or empty string, length will be 0 and will be considered empty.
If the value is 0, false, or other falsy values, then it would be considered not empty. If you want to consider falsey values as empty, this as the first line in the function above:
if(!obj) return true
Thanks to Bergi that lead me to this working solution:
_.every(documentsObject, function(property) { return _.isEmpty(property); });
that returns true if the object is "deep empty", false otherwise.

LoDash _.has for multiple keys

Is there a method or a chain of methods to check if an array of keys exists in an object available in lodash, rather than using the following?
var params = {...}
var isCompleteForm = true;
var requiredKeys = ['firstname', 'lastname', 'email']
for (var i in requiredKeys) {
if (_.has(params, requiredKeys[i]) == false) {
isCompleteForm = false;
break;
}
}
if (isCompleteForm) {
// do something fun
}
UPDATE
Thanks everyone for the awesome solutions! If you're interested, here's the jsPerf of the different solutions.
http://jsperf.com/check-array-of-keys-for-object
I know the question is about lodash, but this can be done with vanilla JS, and it is much faster:
requiredKeys.every(function(k) { return k in params; })
and even cleaner in ES2015:
requiredKeys.every(k => k in params)
You can totally go functional, with every, has and partialfunctions, like this
var requiredKeys = ['firstname', 'lastname', 'email'],
params = {
"firstname": "thefourtheye",
"lastname": "thefourtheye",
"email": "NONE"
};
console.log(_.every(requiredKeys, _.partial(_.has, params)));
// true
We pass a partial function object to _.every, which is actually _.has partially applied to params object. _.every will iterate requiredKeys array and pass the current value to the partial object, which will apply the current value to the partial _.has function and will return true or false. _.every will return true only if all the elements in the array returns true when passed to the function object. In the example I have shown above, since all the keys are in params, it returns true. Even if a single element is not present in that, it will return false.
_(requiredKeys).difference(_(params).keys().value()).empty()
I believe. The key step is getting everything into arrays then working with sets.
or
_requiredKeys.map(_.pluck(params).bind(_)).compact().empty()
Might work.
Assuming that params can have more properties than is required...
var keys = _.keys(params);
var isCompleteForm = requiredKeys.every(function (key) {
return keys.indexOf(key) != -1;
});
Should do the trick.

Categories

Resources