Get number of rows of multidimensional JSON variable - javascript

I have a PHP function that returns a multiple-level JSON object in the format
var data = {
1 : {
1: { Object },
2: { Object },
...,
...
},
2: {
1: { Object },
2: { Object },
...,
...
}
}
I need to get the length of data to initialize a for loop maximum value. By this, I mean the count of the first level entries.
data[1].length returns 22, and data[2].length returns 23 via the console.log printout. This is expected, but data.length returns undefined.
Is there a better method than
var count = 0;
for (var i=1; i< Number.MAX_VALUE; i++){
if (typeof data[i] != 'undefined')
count = i;
}

How About
Object.keys(data).length

If you can control the JSON format, nested arrays seem a better alternative.
If not, you can run something like
var length = 0;
for (var i in data) {
if (isFinite(i) && i > length)
length = i;
}

You can count the number of entries in a loop, like this:
var length = 0;
for (var key in data) {
if (data.hasOwnProperty(key)) {
length++;
}
}
However, if you have control over the returned data, it would probably be easier to return an array instead of an object because the array will already have the length property you want.

Why not just do this instead of assigning numeric properties? Arrays will have the length property you wish:
var data = [
[
{ Object },
{ Object },
...,
...
],
[
{ Object },
{ Object },
...,
...
]
]

Related

remove duplicated array of object using normal for loop

I know there's a shortcut like using loadash's uniq but I try to remove duplicated array of object using a native for loop.
var json = [
{name:"james"},
{name:"james_x"},
{name:"jame"},
{name:"james_x"}
]
for(var i = 0;i<json.length-1;i++){
if(json[i].name == json[i+1].name){
json.splice(i,i);
}
}
console.log(json);
https://jsfiddle.net/8wwnvzoc/
I REALLY want to know what's wrong.
You shouldn't modify an array while you're iterating over it. It will lead to unexpected behavior. I'd recommend building an array of indices to remove and then remove them once you're fully through the array.
To fix your algorithm, you need to keep track of all the names you've seen. You can use an ES6 set for this.
var json = [
{name:"james"},
{name:"james_x"},
{name:"jame"},
{name:"james_x"}
]
var indicesToRemove = [];
var seen = new Set();
for(var i = 0;i<json.length;i++){
if (seen.has(json[i].name)) {
indicesToRemove.push(i)
} else {
seen.add(json[i].name);
}
}
for(index of indicesToRemove.reverse()) {
// iterating backwards to prevent indices changing on us...
json.splice(index,index);
}
console.log(json);
Try sorting the array before looping over it like this:
var json = [
{name:"james"},
{name:"james_x"},
{name:"jame"},
{name:"james_x"}
]
json = json.sort(function(a, b){a=a.name;b=b.name;return a<b?-1:a>b?1:0});
for(var i = 0;i<json.length-1;i++){
if(json[i].name == json[i+1].name){
json.splice(i,1);
}
}
console.log(json);
Then, the equal values will be near each other so your algorithm will work as expected...
EDIT:
A possibly better approach, though not using a loop:
var json = [
{name:"james"},
{name:"james_x"},
{name:"jame"},
{name:"james_x"}
]
json = json
.sort(function(a, b){a=a.name;b=b.name;return a<b?-1:a>b?1:0})
.reduce(function(a, b){var n=a.length;if(n===0||a[n-1].name!==b.name)a[n]=b;return a},[]);
console.log(json);
You can do it like so:
var json = [{
name: "james"
}, {
name: "james_x"
}, {
name: "jame"
}, {
name: "james_x"
}]
const unique = []
json.forEach(function(item) {
var existingName = unique.find(function(name) { return name.name === item.name})
!existingName ? unique.push(item) : null
})
console.log(unique)
You're not checking all other items when testing for duplication. Further you're modifying the array while iterating over it - this might crash.
var json = [
{ name:"james" },
{ name:"james" },
{ name:"james_x" },
{ name:"james_x" },
{ name:"james_x" },
{ name:"jame" },
{ name:"james_x" },
{ name:"jame" },
];
var i = 0,
index = { /* track what we've seen already */ },
current;
while (i < json.length) {
current = json[i].name;
// check if the name is in index
if (current in index) {
// it is, remove it from the array
json.splice(i, 1);
} else {
// not in index, leave it untouched and add it to the index
// by defining a key in "index" with arbitrary value
index[current] = true;
// only step forward when indexing, not when removing
i++;
}
}
The increment is limited to the indexing branch since the algorithm would accidentally skip the next item if it's also a duplicate (the following items would shift left-/upwards).
See the progress (2nd column is the following iteration step of the 1st column):
When incrementing in both branches:
1 1
2 2
3 3
2 <= dupe 2
2 2 <= accidentally incremented
2 4 missed the previous item
4
Correct incrementation:
1 1
2 2
3 3
2 <= dupe 2 <= not incremented, all OK
2 2
2 4
4

pushing strings into an object

I have an array of objects and an array of string and I am tying to combine the two in sequence meaning I would like to first item on the array to be stored only in the first object, second item of the array only in the second object, ect. Something like the following.
var objects = [ obj1, obj2, obj3];
var strings = ["123", "456", "789"];
//Result
var results = [
{
"obj1": {
number: "123"
},
{
"obj2": {
number: "456"
},
{
"obj2": {
number: "789"
}
];
I have been trying to do this with a push and a for loop but I seem to end up with each object containing all three strings.
Its easy:-
for (var i = 0; i < objects.length; i++) {// start loop for getting values one by one from object array
objects[i].number = strings[i]; // assign string values to object array values
}
Matched object and string share the same array index:
for (var i = 0; i < objects.length; i++) {
objects[i].number = strings[i];
}
Or you could do this using the map function:
var results = objects.map(function (value, index) {
return Object.assign({}, value, { number: strings[index] });
});
The other answers are good I just wanted to give you another way. This way you also do not modify the existing objects array
In case you don't know Object.assign add to the first argument (in our case the empty object {}) all the properties from the other object arguments. You can read more about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Also, you can learn here about the map function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Find length of json string

I have following Jsonstring
var j = { "name": "John" };
alert(j.length);
it alerts : undefined, How can i find the length of json Array object??
Thanks
Lets start with the json string:
var jsonString = '{"name":"John"}';
you can easily determine its length:
alert("The string has "+jsonString.length+" characters"); // will alert 15
Then parse it to an object:
var jsonObject = JSON.parse(jsonString);
A JavaScript Object is not an Array and has no length. If you want to know how many properties it has, you will need to count them:
var propertyNames = Object.keys(jsonObject);
alert("There are "+propertyNames.length+" properties in the object"); // will alert 1
If Object.keys, the function to get an Array with the (own) property names from an Object, is not available in your environment (older browsers etc.), you will need to count manually:
var props = 0;
for (var key in jsonObject) {
// if (j.hasOwnProperty(k))
/* is only needed when your object would inherit other enumerable
properties from a prototype object */
props++;
}
alert("Iterated over "+props+" properties"); // will alert 1
Another way of doing this is to use the later JSON.stringify method which will give you an object (a string) on which you can use the length property:
var x = JSON.stringify({ "name" : "John" });
alert(x.length);
Working Example
function getObjectSize(o) {
var c = 0;
for (var k in o)
if (o.hasOwnProperty(k)) ++c;
return c;
}
var j = { "name": "John" };
alert(getObjectSize(j)); // 1
There is no json Array object in javascrit. j is just an object in javascript.
If you means the number of properties the object has(exclude the prototype's), you could count it by the below way:
var length = 0;
for (var k in j) {
if (j.hasOwnProperty(k)) {
length++;
}
}
alert(length);
An alternate in Jquery:
var myObject = {"jsonObj" : [
{
"content" : [
{"name" : "John"},
]
}
]
}
$.each(myObject.jsonObj, function() {
alert(this.content.length);
});
DEMO

Sort complex JSON based on particular key

I have a JSON object with the following format:
{
items:{
nestedObj:{
position:3
},
nestedObj2:{
position:1
},
nestedObj3:{
position:2,
items:{
dblNestedObj:{
position:2
},
dblNestedObj2:{
position:3
},
dblNestedObj3:{
position:1
}
}
}
}
}
I am attempting to sort each level of nested object by their position attribute. I can recursively iterate the object, but I don't know where to start for sorting it...
Unfortunately it's not quite so easy to use the sort method as it would if you had an array. So let's build an array:
var tmp = [], x;
for( x in obj.items) { // assuming your main object is called obj
tmp.push([x,obj.items[x].position]);
// here we add a pair to the array, holding the key and the value
}
// now we can use sort()
tmp.sort(function(a,b) {return a[1]-b[1];}); // sort by the value
// and now apply the sort order to the object
var neworder = {}, l = tmp.length, i;
for( i=0; i<l; i++) neworder[tmp[i][0]] = obj.items[tmp[i][0]];
obj.items = neworder;

Cannot get length of a list

Hay, i have the following list
var feedObjects = {
0:[
"url",
"image"
],
1:[
"url",
"image"
]
}
However when i try doing feedObjects.length it always returns null, any ideas?
You have an Object ({} are the literal Object notation), not an Array, so there is no length property.
You will need to iterate over it with for ( in ), except this guarantees no ordering of the properties, unlike an Array (though in practice they generally come in the order defined).
Better still, swap { } with [ ] and use a real Array (well as close as JavaScript's arrays are to real ones).
You have declared an associative array, not an indexed array. Try this
var feedObjects = [
[
"url",
"image"
],
[
"url",
"image"
]
];
Your object doesn't have a length property or method-
you need to count its members.
var feedObjects={
["url","image"],["url","image"]
}
function count(){
var counter= 0;
for(var p in this){
if(this.hasOwnProperty(p))++counter;
}
return counter;
}
count.call(feedObjects)
returned value: (Number)=2
or define an array:
var feedObjects=[ ["url","image"],["url","image"]];
//feedObjects.length=2;
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
alert(Object.size(feedObjects))

Categories

Resources