仅保留JavaScript对象中的某些属性

use*_*531 16 javascript

我有一个对象.我想通过删除除某些特定属性之外的所有属性来修改对象(而不是克隆它).例如,如果我开始使用此对象:

var myObj={
    p1:123,
    p2:321,
    p3:{p3_1:1231,p3_2:342},
    p4:'23423',
    //....
    p99:{p99_1:'sadf',p99_2:234},
    p100:3434
}
Run Code Online (Sandbox Code Playgroud)

并且只想要属性p1,p2和p100,我该如何获得这个对象:

var myObj={
    p1:123,
    p2:321,
    p100:3434
}
Run Code Online (Sandbox Code Playgroud)

我理解如何用蛮力做到这一点,但想要一个更优雅的解决方案.

Rya*_*yan 19

您可以使用这种方法:

let result = (({ p1, p2, p100 }) => ({ p1, p2, p100 }))(myObj);

我在/sf/answers/1788818601/学到的。


Vis*_*ioN 7

只需重新初始化对象:

myObj = {
    p1:   myObj.p1,
    p2:   myObj.p2,
    p100: myObj.p100
};
Run Code Online (Sandbox Code Playgroud)

另一种方法是删除某些效果较差的属性:

var prop = ['p1', 'p2', 'p100'];
for (var k in myObj) {
    if (prop.indexOf(k) < 0) {
        delete myObj[k];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @JuanMendes它不会克隆它. (2认同)
  • 但是你仍然没有你开始使用的对象 (2认同)
  • 与第一个代码块不同,第二个代码块是有效的.实际上,如果另一个变量引用"myObj"会怎么样? (2认同)
  • @VisioN对第一个对象的任何其他引用怎么办? (2认同)
  • 属性的数量不是问题@ user1032531,关注这句话:"如果你不需要保持对原始对象的引用".给我一点时间,我会发一个答案给你解释一下. (2认同)

Alf*_*Alf 7

这是谷歌搜索'js仅保留某些键'时的第一次打击,因此可能值得更新.

最"优雅"的解决方案可能只是使用underscore.js

_.pick(myObj, 'p1', 'p2', 'p100')
Run Code Online (Sandbox Code Playgroud)

  • ...或`lodash`。 (3认同)

Jua*_*des 5

var myObj = {a: 1, b: 2, c:3};

function keepProps(obj, keep) {
    for (var prop in obj) {
        if (keep.indexOf( prop ) == -1) {
            delete obj[prop];
        }             
    }
}

keepProps(myObj, ['a', 'b']);
console.log(myObj);
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/mendesjuan/d8Sp3/2/

  • @tewathia 请详细说明“暴力”。根据OP的问题,这是最动态的方法。 (3认同)
  • 为什么使用 2 个嵌套循环和“indexOf”? (3认同)

lea*_*eaf 5

你可以使用delete

for (var k in myObj) {
    if (k !== 'p1' && k !== 'p2' && k !== 'p100') {
        delete myObj[k];
    }
}
Run Code Online (Sandbox Code Playgroud)

替代方案indexOf

var take = /^p(1|2|100)$/;
for (var k in myObj) {
    if (!take.test(k)) {
        delete myObj[k];
    }
}
Run Code Online (Sandbox Code Playgroud)

更短:

var take = /^p(1|2|100)$/;
for (var k in myObj) {
    take.test(k) || delete myObj[k];
}
Run Code Online (Sandbox Code Playgroud)

数组到正则表达式:

var take = [1, 2, 100];
take = new RegExp('^p(' + take.join('|') + ')$'); // /^p(1|2|100)$/
take.test('p1'); // true
take.test('p3'); // false
Run Code Online (Sandbox Code Playgroud)

在函数中有用:

function take(o, ids) {
    var take = new RegExp('^p(' + ids.join('|') + ')$');
    for (var k in o) take.test(k) || delete o[k];
    return o;
}
Run Code Online (Sandbox Code Playgroud)

用法:

take(myObj, [1, 2, 100]); // { p1: 123, p2: 321, p100: 3434 }
Run Code Online (Sandbox Code Playgroud)

如果你不喜欢正则表达式:

function take(o, keys) {
    for (var k in o) contains(keys, k) || delete o[k];
    return o;
}

function contains(array, value) {
    var i = -1, l = array.length;
    while (++i < l) if (array[i] === value) return true;
    return false;
}

function prefix(array, prefix) {
    var i = -1, l = array.length, output = [];
    while (++i < l) output.push(prefix + array[i]);
    return output;
}
Run Code Online (Sandbox Code Playgroud)

用法:

take(myObj, ['p1', 'p2', 'p100']);
// with a middleman :
var idsToTake = [1, 2, 100];
take(myObj, prefix(idsToTake, 'p'));
Run Code Online (Sandbox Code Playgroud)


Gra*_*ant 5

Lodash有一个名为的函数pick,它执行您所描述的操作。我知道包含库并不理想,但您也可以在使用捆绑包等时挑选功能。

var myObj={
    p1:123,
    p2:321,
    p3:{p3_1:1231,p3_2:342},
    p4:'23423',
    //....
    p99:{p99_1:'sadf',p99_2:234},
    p100:3434
}

var newObj = _.pick(myObj, 'p1', 'p2', 'p100')
Run Code Online (Sandbox Code Playgroud)