12

Heres a simple example.

function Person() {
  this.name = "Ted";
  this.age = 5;
}

persons[0] = new Person();
persons[1] = new Person();
JSON.stringify(persons);

If I have an array of Person objects, and I want to stringify them. How can I return JSON with only the name variable.

The reason for this is, I have large objects with recursive references that are causing problems. And I want to remove the recursive variables and others from the stringify process.

Thanks for any help!

Marek Sebera
  • 39,650
  • 37
  • 158
  • 244
Moz
  • 1,494
  • 6
  • 21
  • 32

4 Answers4

29

the easiest answer would be to specify the properties to stringify

JSON.stringify( persons, ["name"] )

another option would be to add a toJSON method to your objects

function Person(){
  this.name = "Ted";
  this.age = 5;      
}
Person.prototype.toJSON = function(){ return this.name };

more: http://www.json.org/js.html

lordvlad
  • 5,200
  • 1
  • 24
  • 44
  • 1
    This seems like a better answer then the accepted answer. You can use the `replacer` argument to write a function that would exclude w/e properties you don't want to be serialized in the object. – Josh M. Mar 27 '13 at 11:55
18

If you're only supporting ECMAScript 5 compatible environments, you could make the properties that should be excluded non-enumerable by setting them using Object.defineProperty()[docs] or Object.defineProperties()[docs].

function Person() {
    this.name = "Ted";
    Object.defineProperty( this, 'age', {
        value:5,
        writable:true,
        configurable:true,
        enumerable:false // this is the default value, so it could be excluded
    });
}

var persons = [];

persons[0] = new Person();
persons[1] = new Person();

console.log(JSON.stringify(persons));  // [{"name":"Ted"},{"name":"Ted"}]
user113716
  • 318,772
  • 63
  • 451
  • 440
  • Just a general off the wall question due to my ignorance... What sort of developer is only supporting ECMAScript 5 and what sort of thing is he working on? What is running ECMAScript 5, etc? – Allen Rice Sep 15 '11 at 21:53
  • @Allen: Internal applications for closed environments where browser type/version is ensured. Or server-side code, though this is less likely due to OP's inclusion of the `jQuery` tag. *"What is running ECMAScript 5, etc?"* If you mean what environments support ES 5, check out the [ES 5 compatibility table](http://kangax.github.com/es5-compat-table/) from Kangax. – user113716 Sep 15 '11 at 22:22
  • 1
    Thanks! I saw that table after doing some research, after posting the comment above :) It looks like there are a ton of browsers implementing the features already, very exciting! – Allen Rice Sep 15 '11 at 22:44
  • Thanks guys, can I use something similar to ignore methods as well? I have a function call to a local method during construction of my object e.g. this.method() and this is causing the stringify to mess up still (cyclic object value) – Moz Sep 16 '11 at 00:11
  • @Moz: Is that method is just used during construction, or is it meant to be a member of the `.prototype` object of the constructor. – user113716 Sep 16 '11 at 00:21
  • @Moz: Then don't put it as a property on `this`. If it's only used in construction, then just make it a normal function in the constructor: `function my_method() {...}`. If you want `this` inside the function to reference the same object referenced by `this`, then call it like `my_method.call( this )`. That will set the `this` value inside the function to the same `this` value outside. – user113716 Sep 16 '11 at 00:40
  • Interesting approach, why does stringify works only on enumerable properties? Is that spec'd somewhere ? – Benjamin Gruenbaum Mar 31 '13 at 19:46
3

I would create a new array:

var personNames = $.map(persons,function(person){
  return person.name;
});
var jsonStr = JSON.stringify(personNames);
Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • how would this would if I wanted to return multiple values, could I put them in an array? I don't have access to my code right now to try for myself sorry. – Moz Sep 15 '11 at 22:51
  • you would return a map of properties, such as `return { name: person.name, id: person.id };` – Kevin B Sep 15 '11 at 22:56
  • I can't get this to work, using your code just returns the whole person object still. Are you sure this is correct? The examples for .grep in jQuery API use the function to return a boolean, that determines if the whole object is included in the array. Not to define what variables are included. – Moz Sep 15 '11 at 23:51
  • Sorry, i'm using the wrong method. it should be $.map, i'll update answer. – Kevin B Sep 16 '11 at 00:08
  • one more thing, currently there is returning an object. I actually want arrays of data, arrays within the single array. Is there an easy way to do this? – Moz Sep 16 '11 at 00:44
  • spot on, thanks a lot. I had already tried something similar, but I didnt have the second set of square brackets so everyone was in one giant array, now its 2D, thanks. – Moz Sep 16 '11 at 23:16
-1

see this post specify the field you'd like to include. JSON.stringify(person,["name","Address", "Line1", "City"]) it is match better then what suggested above!

Community
  • 1
  • 1
moshe beeri
  • 2,007
  • 1
  • 17
  • 25