-1

My database returns this kind of User object:

{
    name: "Name",
    surname: "Surname",
    scores: [<array of scores here>],
    facebook_id: "fb_id_here",
    access_token: "4y8y09n3vy09y0",
    last_login: "some date",
    register_date: "somedate"
    sessions_count: 453
}

Is there any faster way of creating object containing only some key-value pairs than creating a new one with selected fields? Something like:

var NewObject = UserObject.filterFields([name, surname, sessions_count, scores]);

which should produce:

{
    name: "Name",
    surname: "Surname",
    scores: [<array of scores here>],
    sessions_count: 453
}

Thanks.

Rafal Wiliński
  • 2,240
  • 1
  • 21
  • 26
  • 1
    Any faster way than what? You forgot the code. – RobG Sep 19 '15 at 08:32
  • Than creating new one like this: `var newObject = { name: UserObject.name surname: UserObject.surname, scores: UserObject.scores, sessions_count: UserObject.sessions_count } ` – Rafal Wiliński Sep 19 '15 at 08:35
  • Look at lodash's `pick` and `omit`. – Ori Drori Sep 19 '15 at 08:38
  • See http://stackoverflow.com/questions/30496010/filter-json-data-by-property-in-javascript/30496773#30496773, http://stackoverflow.com/questions/25527554/filtering-out-keys-from-a-javascript-object/25540704#25540704. Also, I presume you're asking for "faster" because you have profiled your code and narrowed down your performance problem to this part of your code? By the way, your specified syntax (`filterFields([name, ...]`) is going to be invalid syntax and cause a ReferenceError because `name` is not defined. –  Sep 19 '15 at 10:47

2 Answers2

0
var UserObject = {
    name: "Name",
    surname: "Surname",
    scores: [1,2,3],
    facebook_id: "fb_id_here",
    access_token: "4y8y09n3vy09y0",
    last_login: "some date",
    register_date: "somedate",
    sessions_count: 453
};

function filterFields(obj, fields) {
    return fields.reduce(function(ret, field) {
        ret[field] = obj[field];
        return ret;
    }, {});
}
var NewObject = filterFields(UserObject, ['name', 'surname', 'sessions_count', 'scores']);
console.log(NewObject);

With the function, you could also do soemthing like

UserObject.filterFields = filterFields.bind(UserObject, UserObject);

then

var NewObject2 = UserObject.filterFields(['name', 'surname', 'sessions_count', 'scores']);

console.log(NewObject2);
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Not the downvoter, but perhaps the downvoter had ethical issues with the use of `reduce` here. Normally, reduce is considered to be a way to "reduce" an array to a single value, such as finding the sum of the array to take the very simplest example. Of course the way you use it is admittedly very common, but it also seems to violate some notion about what reduce should be used for. Instead of using it to "boil down" an array into a value, you're using it as a sort of `forEach` with a "free" built-in variable. –  Sep 19 '15 at 11:01
  • free built in variables rock – Jaromanda X Sep 19 '15 at 11:42
  • @torazaburo—that may be an inference from the name, however the specification doesn't define or suggest how it should be used. MDN says "*… reduce it to a single value*" which is a similar inference, but the array itself isn't mutated. It's really just another form of *forEach* that avoids declaration of the initial value and returns it. Perhaps *generate* would be a better name, as it generates a new value. – RobG Sep 19 '15 at 22:30
0

There are many ways to do this. If you include ES6, there are even more ways. You can modify the object by deleting keys; or you can create a new object with only the fields you want. Here's one simple idea:

// Copy values for properties present on o1 from o2.
define copyFrom(o1, o2) {
  Object.keys(o1).forEach(function(key) { o1[key] = o2[pkey]; });
}

Since you seem to want to be able to call this as a method on the object:

Object.defineProperty(Object.prototype, 'filterFields', {
  value: function(o) { copyFrom(o, this); }
});

Now you can call this as

var NewObject = UserObject.filterFields({name: 0, surname: 0, session_count: 0, scores: 0});

The idea of using an object like {name: 0, ... to specify the keys you want may seem a bit clumsy. On the other hand, speciyfing the keys as strings is not very aesthetically pleasing either.