I have a requirement to find whether variable is Object array or not, below is the example data:
var myColumnDefs = [
{key:"label", sortable:true, resizeable:true},
{key:"notes", sortable:true,resizeable:true}];
If I do
jQuery.type(myColumnDefs) then it will say it's an array
but how can i find whether it's object array or not?
If I iterate each element in array and check for object with jQuery.isPlainObject() then also it won't work because it will check only for plain objects like jQuery.isPlainObject({}).
Arrays in javascript aren't typed, and so you will have to check each that each and every element of the array is an object.
For instance:
var isObjectArray = true;
myColumnDefs.forEach(function(elem) {
if (typeof elem === "object")
isObjectArray = false;
});
Here is a re-usable function:
function isObjectArray(arr) {
for (var i = 0; i < arr.length; i++)
if (typeof arr[i] !== "object")
return false;
return true;
}
Related
I've got an array that has a lot of objects and embedded arrays. I need to iterate through the entire array to see if anything is empty or null. My problem is checking Arrays and whether or not the arrays return empty. I keep getting object arrays and they are not null or undefined so get added in even if length is 0. What I've got so far.
var progressCount = 0;
var progressKeyLength = progressBarCriteria.length;
for (var i = 0; i<progressKeyLength; i++){
//I can find the arrays here but still not able to check length since they are actually object arrays.
if(Array.isArray(progressBarCriteria[i])){
console.log('array' + i);
}
if (progressBarCriteria[i] !== null && progressBarCriteria[i] !== ""){
++progressCount
}
}
progressBarCritiria = [
example1: "",
example2: "asdasdas",
example3: 233,
example4: {asda: 1},
example5: {asadasda: "asdasdA"},
example6: "",
example7: [],
example8: [1, 12312],
example9: [{1: "ad"}, {1: 12312}],
]
So 1, 6 and 7 should not be added to my count.
If you need to check the length or null value for an array, you can think about the Truthy - Falsy value as follow:
if (Array.isArray(progressBarCriteria[i]) && progressBarCriteria[i].length) {
// This is an array and is not empty.
}
This Array.isArray(progressBarCriteria[i]) checks if that value is an array.
If this progressBarCriteria[i].length is 0 the boolean value will be false, ortherwise will be true.
You can use a recursive function to do that. It is important to notice that in javascript arrays are objects. So you need to check for objects by if (typeof arr === 'object' && !(arr instanceof Array)). For more informations check this and this.
function recursive_array_chekc (arr) {
//check if arr is an object
if (typeof arr === 'object' && !(arr instanceof Array)) {
//check if object empty
if (Object.keys (arr).length === 0) {
//do something if empty
console.log ('this object is empty');
} else {
//check object properties recursivly
for (var key in arr)
if (arr.hasOwnProperty (key))
recursive_array_chekc (arr[key])
}
} else
if (Array.isArray (arr)) {
//check if array is empty
if (arr.length === 0) {
//do something if empty
console.log ('this array is empty');
} else {
//check array elements recursivly
for (var i = 0; i < arr.length; i++)
recursive_array_chekc (arr[i])
}
}
}
I was able to look at both answers and came up with this working solution. This is using Typescript so sorry for confusion.
for (var i = 0; i<progressKeyLength; i++){
if (!(progressBarCriteria[i] instanceof Array)){
if(progressBarCriteria[i] !== null && progressBarCriteria[i] !== "") {
++progressCount
}
} else {
let current = progressBarCriteria[i];
if (Array.isArray(current) && current.length !== 0){
++progressCount
}
}
}
I have an array of JSON objects imdb and I want to check if a key exists. I have tried couple different methods but none of them shows the correct result. I looked into this post but doesn't help. Below code
var imdb = [{"123":"hi"}, {"234":"hello"}]; //array of JSON object
var valEventTime = 123; //key I want to find if exists
//approach 1
function getValueByKey(key, data) {
var i, len = data.length;
for (i = 0; i < len; i++) {
if (data[i] && data[i].hasOwnProperty(key)) {
return data[i][key];
}
}
return -1;
}
if(getValueByKey(valEventTime, imdb) > -1){
console.log("Yes");
}
else {
console.log("NOT")
}
//approach 2
if (imdb[valEventTime]) {
console.log("Yes");
} else {
console.log("NOT")
}
//approach 3
var keys=Object.keys(imdb)
for(var i=0;i<keys.length;i++){
if(keys[i]==valEventTime)
{//check your key here
console.log("Yes")
}
else console.log("NOT")
}
The output always shows NOT even though I am searching for a key that already exists (123). Please suggest.
The problem with your solution is that you are trying to search for a integer key where as your json key is a string.
var imdb = [{"123":"hi"}, {"234":"hello"}]; // key is string
var valEventTime = 123; // key is integer
var imdb = [{"123":"hi"}, {"234":"hello"}];
var valEventTime = "123";
var obj = imdb.some((val) => {
return Object.keys(val).includes(valEventTime);
})
console.log(obj);
You can use Array.some() to determine if an array contains a value. For each item you want to use the Array.includes() function to check for your variable for the items return from Object.keys() on each entry. In your example your variable is an integer and the key is a string - you may want to be more specific in your matching.
var imdb = [{"123":"hi"}, {"234":"hello"}];
var valEventTime = "123"; // use a string to match the keys
// use Array.some() to loop through each item and short circuit when we return true
var hasKey = imdb.some(function(movie) {
// get the object keys as an array and see if that array contains your variable
// returning true will also return true from Array.some()
return Object.keys(movie).includes(valEventTime);
});
I'm completely new to using Jquery, and I'm trying push unique objects to an array, and if the object is already in the array, it removes them. This is for students to book multiple tutorial classes by clicking on available options, and then submitting the full array with all their selected options.
I've updated my code exactly from what I've written. This code works perfectly if I just use single elements in the array. It cannot evaluate duplicate selected slots if I use objects in the array.
var bookingSlots = [];
$('.row').on('click','.slots', function (e) {
e.preventDefault();
$(this).toggleClass('selected');
var slotID = $(this).attr('data-slot-id');
var studentID = $(this).attr('data-student-id');
var slot = {slotID: slotID, studentID: studentID};
var found = jQuery.inArray(slot,bookingSlots);
if(found < 0){
bookingSlots.push(slot);
}else{
bookingSlots.splice(found, 1);
}
});
From your comment:
the object is being created on every single click
That's the problem: Equivalent objects are not either == or === to each other, and inArray uses === to find the object. For instance, $.inArray({id:1}, [{id:1}]) returns -1:
console.log($.inArray({id:1}, [{id:1}])); // -1
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
So you'll want to use something else. On modern browsers, you can use Array#findIndex and use a predicate function:
var index = array.findIndex(function(e) { return e.id == id && e.id2 == id2; });
Example:
var array = [];
run(1, 1); // adds
run(1, 2); // adds
run(1, 1); // removes
console.log(array); // ends up with just the 1,2 object in it
function run(id, id2) {
// Find the equivalent object if any
var index = array.findIndex(function(e) { return e.id == id && e.id2 == id2; });
// Found?
if (index == -1) {
// No, add one
array.push({id: id, id2: id2});
} else {
// Yes, remove it
array.splice(index, 1);
}
}
Array#findIndex can be shimmed/polyfilled on older browsers; MDN has a polyfill here (I've also quoted it below, just in case, but I can't imagine MDN disappearing any time soon).
Side note: It's a bit more concise with ES2015 (aka "ES6") (browsers aren't quite ready for us to use ES2015 in the wild yet, but you can transpile):
let index = array.findIndex(e => e.id == id && e.id2 == id2);
Here's MDN's polyfill as of this writing (25/05/2016):
if (!Array.prototype.findIndex) {
Array.prototype.findIndex = function(predicate) {
if (this === null) {
throw new TypeError('Array.prototype.findIndex called on null or undefined');
}
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
var value;
for (var i = 0; i < length; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) {
return i;
}
}
return -1;
};
}
In your situation, I suggest that you should take a look on LINQ JS
Example:
var exObjArr = Enumerable.From(array)
.Where(function(x){return x.id1 == object.id1 && x.id2 == object.id2})
.ToArray();
if(exObjArr.length == 0){
//object does not exist
} else{
//object exists
}
I have been working on a function that loops through a JSON object recursively, and want to use each key it finds as the class value of an element to change the .text value of that element in jQuery. So, far so good, however, as I am able to get the Keys recursively as well, I'm struggling on finding a way to input all of those keys to get each json objects values:
function eachRecursive(obj, aKey)
{
aKey = aKey === null ? '' : aKey;
for (var k in obj)
{
if (typeof obj[k] == "object" && obj[k] !== null)
{
aKey += k + '_';
eachRecursive(obj[k], aKey);
}
else
{
if (obj.hasOwnProperty(k))
{
console.log(obj[k]);
if ($('.player_' + aKey + k).length)
{
var props = aKey.split('_');
props.clean("");
$('.player_' + aKey + k).text(obj[k]);
}
}
// might not even need this.
aKey = '';
}
}
}
So, text(obj[k]) isn't going to work here since the json is looping through objects inside objects recursively.
So, aKey is a string that gets used to check if the class exists (should be appending each key of the json object into it. Than should check if exists, if it does exist, should plug in the value into the .text of that element.
But what I'm sruggling here with is how to get the value from all of the keys that get plugged into an array called, props. So I will need to use each value in the array as keys for obj object to get the corresponding json value.
Can someone please help me here?
The .clean prototype added to Array just simply removes any empty values in the array. Specifically the last array index (since it splits on _).
How to pass array values into obj to get the json value?
For Example, if:
var props = ['name', 'first', 'last'];
// How to do this so we can get the value?
obj['name']['first']['last'][k]
Iterate over the props array and lookup the value in turn using bracket notation.
var value = obj;
for (var i = 0; i < props.length; i++) {
value = value[props[i]];
}
value = value[k];
Say I have this object:
{
"prop1":"Hello",
"prop2":{
"prop1":{
"prop1":"Tablecloth",
"prop2":"Indians"
},
"prop2":"JuicyJuice"
},
"prop3":"Sponge",
"prop4":{"Bob":"Squarepants"}
}
I would like a recursive function that will return HelloTableclothIndiansJuicyJuiceSpongeSquarepants.
Whatever object I put it, I want it to cycle though until it gets all of the strings and adds them all up.
Thank you!
Here's a very simple implementation that should work for simple objects like this:
var walkProps = function(obj) {
var s = "";
for(var x in obj)
{
if(typeof obj[x] === "string")
s += obj[x];
else
s += walkProps(obj[x]);
}
return s;
}
Demonstration
Note, though, that that depends on the order in which for-in visits the properties on the object, which is not specified and can vary by engine and by how the object is constructed (for instance, the order in which the properties were added).
Update: With some slight modification, this can be used to return the values based on the alphabetical order of the keys. This method is not sensitive to implementation-dependent ordering of properties:
var walkProps = function(obj) {
var s = "", i = 0, keys = Object.keys(obj).sort(), i;
for(; i < keys.length; i++)
{
if(typeof obj[keys[i]] === "string")
s += obj[keys[i]];
else
s += walkProps(obj[keys[i]]);
}
return s;
}
So even if "prop3" comes before "prop2" it will still return the same output.
Demonstration
You would need to write a function that loops over an object's properties and see if they are a string, and then append the strings to an output. If the property is an object rather than a string, you would want to call the function on this object and append it's return value to your total output.
You can loop over an object's properties using for...in like:
var MyObject = {
'a': 'string1',
'b': 'string2'
};
for (var key in MyObject) {
var value = MyObject[key];
}
To check if a property is a string you would want to do:
typeof value === "string"
Which will return true/false accordingly.
As mentioned, for( var b in a ) may not preserve ordering:
// Return array of string values
function getStrings(a) {
if( typeof(a) == "string" ) return [a];
var list = [];
for( var b in a ) list = list.concat(getStrings(a[b]));
return list;
}
Applied to OP's data:
var a = {
"prop1":"Hello",
"prop2":{
"prop1":{
"prop1":"Tablecloth",
"prop2":"Indians"
},
"prop2":"JuicyJuice"
},
"prop3":"Sponge",
"prop4":{"Bob":"Squarepants"}
}
getStrings(a).join(); // "Hello,Tablecloth,Indians,JuicyJuice,Sponge,Squarepants"
// Or as asked for by OP (again, order is not guaranteed)
getStrings(a).join(''); // "HelloTableclothIndiansJuicyJuiceSpongeSquarepants"