Get index of array of objects via jquery - javascript

I have the following array:
var = array[
{"id" : "aa", "description" : "some description"},
{"id" : "bb", "description" : "some more description"},
{"id" : "cc", "description" : "a lot of description"}]
and I try to find the index of the array that contains the id === "bb". The solution I came up with is the following:
var i = 0;
while(array[i].id != "bb"){
i++;
}
alert(i) //returns 1
Is there an easier way that has cross-browser functionality? I tried $.inArray(id,array) but it doesn't work.

I don't see any problem with the complexity of your code, but I would recommend a couple of changes including adding some validation in case the value does not exists. Further more you can wrap it all in a reusable helper function...
function getArrayIndexForKey(arr, key, val){
for(var i = 0; i < arr.length; i++){
if(arr[i][key] == val)
return i;
}
return -1;
}
This can then be used in your example like so:
var index = getArrayIndexForKey(array, "id", "bb");
//index will be -1 if the "bb" is not found
Here is a working example
NOTE: This should be cross browser compatible, and will also likely be faster than any JQuery alternative.

var myArray = [your array];
var i = 0;
$.each(myArray, function(){
if (this.id === 'bb') return false;
i++;
})
console.log(i) // will log '1'
Update with modern JS.
let index
myArray.map(function(item, i){
if (item.id === 'cc') index = i
})
console.log(index) // will log '2'

inArray can't work with multidimensional array so try like the following
var globalarray= [
{"id" : "aa", "description" : "some description1"},
{"id" : "bb", "description" : "some more description"},
{"id" : "cc", "description" : "a lot of description"}];
var theIndex = -1;
for (var i = 0; i < globalarray.length; i++) {
if (globalarray[i].id == 'bb') {
theIndex = i;
break;
}
}
alert(theIndex);
Demo

You can use jQuery.each - http://api.jquery.com/jQuery.each/
var i;
jQuery.each(array, function(index, value){
if(value.id == 'bb'){
i = index;
return false; // retrun false to stop the loops
}
});

Object.keys(yourObject).indexOf(yourValue);

Related

Javascript JSON Loop not counting more than 1 entry

I am reading some json code and at the end added a log that would give me the id.
My problem is that although there are 2 entries the log is only counting 1 and stops there.
var json = [{"main":[{
"id" : "1",
"msg" : "hi",
"tid" : "2013-05-05 23:35",
"fromWho": "hello1#email.se"
},
{
"id" : "2",
"msg" : "there",
"tid" : "2013-05-05 23:45",
"fromWho": "hello2#email.se"
}]}];
for(var i = 0; i < json.length; i++) {
var obj = json[i];
console.log(obj['main'][i].id);
}
Why is it only counting the 1 and not the 2 ?
A few of the answers here are going to confuse the hell out of you! They're missing the fact that you have an array within an object within an array.
json is an array, with 1 element
that object has a property main which itself is an array
it is this "3rd level" array which you are trying to loop through
var json = [{"main":[{
"id" : "1",
"msg" : "hi",
"tid" : "2013-05-05 23:35",
"fromWho": "hello1#email.se"
},
{
"id" : "2",
"msg" : "there",
"tid" : "2013-05-05 23:45",
"fromWho": "hello2#email.se"
}]}];
for(var i = 0; i < json[0].main.length; i++) {
var obj = json[0].main[i];
console.log(obj.id);
}
This happens because your array contains one object. I guess you need to access the main property:
for(var i = 0; i < json[0].main.length; i++) {
console.log(json[0].main[i].id);
}
var json = [{"main":[{
"id" : "1",
"msg" : "hi",
"tid" : "2013-05-05 23:35",
"fromWho": "hello1#email.se"
},
{
"id" : "2",
"msg" : "there",
"tid" : "2013-05-05 23:45",
"fromWho": "hello2#email.se"
}]}];
for(var i = 0; i < json[0].main.length; i++) {
console.log(json[0].main[i].id);
}
json is an array of object. So json[0] will return the main object
Use forEach to loop through the array
var _getMain = json[0].main // will return main array;
_getMain.forEach(function(item){
document.write('<pre>'+item.id+'</pre>')
})
JSFIDDLE
You have an array with 1 element ( 'main' ) and in the 'main' you have an array with 2 elements
Change to this:
for(var i = 0; i < json[0].length; i++) {
console.log(json[0][i].id);
}
Because you have to loop through json[0].main, not through json...

Javascript - Fetch the next letter from an array of objects

So I have an array of objects. Really the objects follow the GeoJSON specification, so keep that in mind. Within the "properties" objects, exists a proerty of "name". This name will be A, B, C... blah ... Z, AA, AB, etc. etc. for each different feature. See JSON example (I did strip out some other things which weren't important to this question, such as the geometry and what not...):
{
"features" : [{
"properties" : {
"name" : "A",
"description" : null,
},
"type" : "Feature"
}, {
"properties" : {
"name" : "B",
"description" : null,
},
"type" : "Feature"
}, {
"properties" : {
"name" : "C",
"description" : null,
},
"type" : "Feature"
}
],
"type" : "FeatureCollection"
}
What I'd like to do is find the MAX letter within this array of features to return the next one in the series. In this example, 'C' would be considered the MAX, so I should need to return the value of 'D'. If I had AA, that would be considered the MAX, and it would return 'AB'. If the max value happened to be a 'Z', I'd like to return a value of 'AA'.
Can ignore use of lowercase and only utilize 26, upper-cased english letters. No other characters.
I believe I could solve this with some usage of the javascript CharCodeAt(index) as well as applying Math.max, adding + 1, then converting back to it's ascii character represenation... but I'm having trouble bringing this together in a working function that loops through all this stuff.
Help would be appreciated!
Update:
I got it partially working with the following code. However haven't quite figured out how to get it to work if it wraps around from Z to AA. Or if the MAX is found to be AF, then returning AG. AZ would have to return BA.
String.fromCharCode(Math.max.apply(Math,someObject.features.map(function(o){return o.properties.name.charCodeAt(0);})) + 1)
Other known rules:
Upper limit can be ZZ - highly unlikely I'd need to wrap back to AAA
The max character will not always be last in the array, so can't
simply get the last feature of the array.
The solution using Array.sort, String.fromCharCode and String.charCodeAt functions:
var someObject = {
"features" : [{
"properties" : { "name" : "AB", "description" : null},
"type" : "Feature"
}, {
"properties" : {"name" : "B", "description" : null},
"type" : "Feature"
}, {
"properties" : { "name" : "AF", "description" : null},
"type" : "Feature"
}
],
"type" : "FeatureCollection"
};
function getNext(data) {
data.features.sort(function(a,b){
return a.properties.name.length - b.properties.name.length ||
a.properties.name.localeCompare(b.properties.name);
});
var last = data.features[data.features.length - 1].properties.name;
if (last.length === 1) {
return (last === "Z")? "AA" : String.fromCharCode(last.charCodeAt(0) + 1);
} else {
if (last === "ZZ") return last; // considering 'ZZ' as a limit
if (last[1] !== "Z") {
return last[0] + String.fromCharCode(last[1].charCodeAt(0) + 1);
} else if (last[1] === "Z"){
return String.fromCharCode(last[0].charCodeAt(0) + 1) + "A";
}
}
}
console.log(getNext(someObject)); // 'AG'
You can find the MAX string with:
var maxName = null,
obj = null,
name = null;
for(var idx = 0; idx < features.length; ++idx){
obj = features[idx];
name = obj.properties.name;
if(maxName == null || name.length > maxName.length ||
(name.length == maxName.length && name > maxName)
){
maxName = name;
}
}
I'm still working on getting the next name though.
I think you want to sort, which actually JS has a nice feature for comparing strings. However, it would return that ("AA" > "Z") === true so you want to account for length as well.
I think this works.
function sortName(a, b){
a = a.properties.name;
b = b.properties.name;
if(a.length>b.length){
return 1;
}
if(a > b){
return 1;
}
return -1;
}
console.log(someObject.features.sort(sortName)[0]. properties.name);
You can do it using
var obj = {
"features": [{
"properties": {
"name": "A",
"description": null,
},
"type": "Feature"
}, {
"properties": {
"name": "B",
"description": null,
},
"type": "Feature"
}, {
"properties": {
"name": "C",
"description": null,
},
"type": "Feature"
}],
"type": "FeatureCollection"
};
var largest = Math.max.apply(Math, findProp(obj.features, "name"));
console.log(changeToStr(largest + 1));
Where findProp is getting the property value array, changeToStr is converting number to string and changeToNum is converting number to String.
function changeToNum(val) {
var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
i, j, result = 0;
for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
}
return result;
};
function changeToStr(number) {
var baseChar = ("A").charCodeAt(0),
letters = "";
do {
number -= 1;
letters = String.fromCharCode(baseChar + (number % 26)) + letters;
number = (number / 26) >> 0;
} while (number > 0);
return letters;
}
function findProp(obj, key, out) {
var i,
proto = Object.prototype,
ts = proto.toString,
hasOwn = proto.hasOwnProperty.bind(obj);
if ('[object Array]' !== ts.call(out)) out = [];
for (i in obj) {
if (hasOwn(i)) {
if (i === key) {
out.push(changeToNum(obj[i]));
} else if ('[object Array]' === ts.call(obj[i]) || '[object Object]' === ts.call(obj[i])) {
findProp(obj[i], key, out);
}
}
}
return out;
}
See the working Fiddle here.

Filtering JSON Array

I need to add filter option to my grid.I use Fixed Data Table.Here is simple filtering example with that grid.
https://github.com/facebook/fixed-data-table/blob/master/examples/old/FilterExample.js
This example filter the Json array only by first name.But I need to filter by all of the objects in JSON Array.
For example may JSON array is here:
{"id":7,"first_name":"Sarah","last_name":"Hottie",
"country":"Sweden","salary":12000},
{"id":9,"first_name":"Mary","last_name":"Parah",
"country":"Argentina","salary":10000}
When I write "arah" to the general input filter value.I need to show both of the two elements of array.Because "id:7" first name (Sarah) and "id:9" last name (Parah) include my filter value ("arah").
If the country value of the another element of JSON array include "arah" I need to show that too.
So I need to filter the JSON array by all of the values it include.
What do you suggest?
You can utilize the filter prototype of the array. It will be something like this:
var arr = [ {"id":7,"first_name":"Sarah","last_name":"Hottie",
"country":"Sweden","salary":12000}, {"id":9,"first_name":"Mary","last_name":"Parah","country":"Argentina","salary":10000}]
var runFilter = function(arr,searchKey) {
var filterFn = function(obj) {
// Iterate the obj for each key.
for (var k in obj) {
if (typeof obj[k] == "string" && obj[k].indexOf(searchKey) >= 0) {
return true;
}
}
}
return arr.filter(filterFn);
}
var filteredArr = runFilter(arr,'arah')
I suggest to use Array#filter in combination with Array#some and a check of the type.
var data = [{ "id": 7, "first_name": "Sarah", "last_name": "Hottie", "country": "Sweden", "salary": 12000 }, { "id": 9, "first_name": "Mary", "last_name": "Parah", "country": "Argentina", "salary": 10000 }],
search = 'arah',
result = data.filter(function (a) {
return Object.keys(a).some(function (k) {
if (typeof a[k] === 'string' && ~a[k].indexOf(search)) {
return true;
}
if (typeof a[k] === 'number' && ~a[k] === search) {
return true;
}
});
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
You can find the filter function in line 45 of the example code. It is
return row['firstName'].toLowerCase().indexOf(filterBy.toLowerCase()) >= 0
If you want to look into every part of an Object, you can use a for...in loop:
for(var key in row){
if((row[key] + "").indexOf(filterBy) > -1){
return true;
}
}
return false;
Replace line 45 with the code above and you should be fine.
Try This :
<script type="text/javascript">
var arr = [ {"id":7,"first_name":"Sarah","last_name":"Hottie","country":"Sweden","salary":12000},
{"id":8,"first_name":"Mary","last_name":"Parah","country":"Argentina","salary":10000},
{"id":9,"first_name":"Gold","last_name":"sonam","country":"India","salary":15000}];
var filterKey = 'arah';
function findJsonString(arr,filterKey){
var result = [];
for (var i = arr.length - 1; i >= 0; i--) {
var part1 = arr[i].first_name.indexOf(filterKey);
var part2 = arr[i].last_name.indexOf(filterKey);
// console.log(arr[i]);
// console.log(' part 1 : ' + part1 + ' part 2 : ' + part2);
if(part1 != -1 || part2 != -1)
{
result[+i] = arr[i];
// OR result.push(arr[i]);
}
}
return result;
}
console.log(findJsonString(arr,filterKey));
</script>
OUTPUT :
[Object { id=7, first_name="Sarah", last_name="Hottie", more...}, Object { id=8, first_name="Mary", last_name="Parah", more...}]

Find item in array based on text

I have an array of objects in a known format, it could look like this:
var items = [{id : 1,
desc : "Funny things",
tags : ["Snippet","Funny"],
title : "Awsome"},
{id : 2,
desc : "Hello World",
tags : ["Fun","Funny"],
title : "What"},
{id : 3,
desc : "True story",
tags : ["Snippet","Cool"],
title : "Is it possible with things?"
}];
I want to create some serach ability in my page that serach for diffrent things inside the items and later display it in some way. Does any one know a plugin that could help me with this?
I was just trying using jQuery grep function and came up with this snippet for my example:
var serach = "things"; // Try to get the tags
var obj = $.grep(items, function(n, i){
// Condition one
if(n.desc.indexOf(serach)>=0)
{
return true;
};
// Condition two
if(n.title.indexOf(serach)>=0)
{
return true;
};
// Condition there
var foundTag = false;
for(var i = 0; i<n.tags.length;i++){
if(n.tags[i].indexOf(serach)>=0)
{
foundTag = true;
return true;
};
}
if(foundTag){return true};
return false;
});
http://jsfiddle.net/Az2rA/1/
It's pretty straight forward and works. However it dosn't solve things like priority diffrent properties. How could add a priority to the function. For example, if the serach expression is found in the title it should apper higher in the "matched" array.
So if anyone have any good input or a good plugin I will find it helpful!
You can use jQuery.each creating and array with a weight for each match and then a sort.
Like this:
//var serach = "Fun"; Try the tags
var serach = "things"; // Try to get the tags
var obj = [];
$.each(items, function(i, n) {
// Condition one
if(n.desc.indexOf(serach)>=0)
{
obj.push({ weight: 0, value: n });
};
// Condition two
if(n.title.indexOf(serach)>=0)
{
obj.push({ weight: 10, value: n });
};
// Condition there
var foundTag = false;
for(var i = 0; i<n.tags.length;i++){
if(n.tags[i].indexOf(serach)>=0)
{
foundTag = true;
obj.push({ weight: 5, value: n });
};
}
if(foundTag){
obj.push({ weight: 5, value: n });
};
});
obj.sort( function(a, b) {
return a.weight < b.weight;
});
​
You can use the map method to wrap each found object into another object along with a priority value. Then you can sort the array on the priority value:
var search = "things";
var obj = $.map(items, function(n, i){
if (n.desc.indexOf(search) != -1) {
return { obj: n, p: 1 };
};
if (n.title.indexOf(search) != -1) {
return { obj: n, p: 2};
};
for (var i = 0; i < n.tags.length; i++) {
if (n.tags[i].indexOf(search) != -1) {
return { obj: n, p: 3}
};
}
return null;
});
obj.sort(function(a, b) {
return a.p == b.p ? 0 : a.p < b.p ? -1 : 1;
});

JSON count an Array elements and wrap in

Well I've just discovered JSON today but I have a problem using it correctly. I really can't find a solution...
Basically, I just want to count the elements of my array (count all the dM), and wrap on a specific element (dM1 for example).
Here is my code so that you can understand: http://jsfiddle.net/dRycS/9/
Adding to what #Pointy said here is your code modified:
JSFiddle Demo
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
var dMContent = {
"dM1" : [
{
"name" : "EeEeEeEe",
"link" : "http://test.com"
},
{
"name" : "FfFfFfFf",
"link" : "http://test.com"
},
{
"name" : "GgGgGgGg",
"link" : "http://test.com"
}
],
"dM2" : [
{
"name" : "EeEeEeEe",
"link" : "http://test.com"
},
{
"name" : "FfFfFfFf",
"link" : "http://test.com"
}
],
"dM3" : [
{
"name" : "EeEeEeEe",
"link" : "http://test.com"
}
]
};
var STORAGE = JSON.stringify(dMContent);
var parsed = JSON.parse(STORAGE);
// WHAT I WANT TO DO
// Count the number of dM
console.log(Object.size(parsed)); //gives you 3
//display the content
for(var i in parsed){
console.log('data in ' + i);
for(var j=0; j<parsed[i].length; j++){
console.log(parsed[i][j].name + ' ' + parsed[i][j].link);
}
}
What you've got there is not an Array; it's an Object. Array objects do have a "length" property, but Objects do not.
It's not clear exactly what you want; if you wanted to count every property of every object inside of "dMContent", you'd write something to count recursively. For a single "layer" of an object, something like this might be what you want:
function objectSize(obj) {
var count = 0;
for (var k in obj) {
if (obj.hasOwnProperty(k)) ++count;
}
return count;
}
In your code dMContent is an Object, not an Array.
To count elements in an Object, do this:
var i = 0;
for (x in parsed) {
if (parsed.hasOwnProperty(x)) {
i++;
}
}
alert(i);
Try this:
function objectCount(obj) {
objectcount = 0;
$.each(obj, function(index, item) {
objectcount = objectcount + item.length;
});
return objectcount;
}
objectCount(obj);
where obj is a json object with json array as sub objects

Categories