【问题标题】:Filter Javascript object or remove many fields at once过滤 Javascript 对象或一次删除多个字段
【发布时间】:2015-09-19 08:27:49
【问题描述】:

我的数据库返回这种用户对象:

{
    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
}

有没有比创建一个包含选定字段的新对象更快的方法来创建只包含一些键值对的对象?比如:

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

应该产生:

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

谢谢。

【问题讨论】:

  • 比什么更快的方法?你忘记了密码。
  • 比这样创建一个新的:var newObject = { name: UserObject.name surname: UserObject.surname, scores: UserObject.scores, sessions_count: UserObject.sessions_count }
  • 看看lodash的pickomit
  • stackoverflow.com/questions/30496010/…stackoverflow.com/questions/25527554/…。另外,我认为您要求“更快”,因为您已经分析了代码并将性能问题缩小到代码的这一部分?顺便说一句,您指定的语法 (filterFields([name, ...]) 将是无效语法并导致 ReferenceError 因为 name 未定义。

标签: javascript object filter


【解决方案1】:
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);

有了这个功能,你还可以做类似的事情

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

然后

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

console.log(NewObject2);

【讨论】:

  • 不是反对者,但可能反对者在此处使用reduce 存在道德问题。通常,reduce 被认为是一种将数组“减少”为单个值的方法,例如找到数组的总和以采取最简单的示例。当然,你使用它的方式是非常普遍的,但它似乎也违反了关于 reduce 应该用于什么的一些概念。您不是使用它来将数组“归结”为一个值,而是将其用作一种带有“免费”内置变量的forEach
  • 免费内置变量rock
  • @torazaburo——这可能是从名称推断出来的,但是规范没有定义或建议应该如何使用它。 MDN 说“…将其减少为单个值”,这是一个类似的推论,但数组本身并没有发生变异。它实际上只是 forEach 的另一种形式,它避免了初始值的声明并返回它。也许 generate 会是一个更好的名称,因为它会生成一个新值。
【解决方案2】:

有很多方法可以做到这一点。如果你包含 ES6,还有更多的方法。您可以通过删除键来修改对象;或者您可以创建一个仅包含所需字段的新对象。这是一个简单的想法:

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

因为您似乎希望能够将其作为对象上的方法调用:

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

现在你可以把它称为

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

使用像{name: 0, ... 这样的对象来指定您想要的键的想法可能看起来有点笨拙。另一方面,将键指定为字符串也不太美观。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多