2015-12-23 5 views
0

Ситуация:Каков наилучший способ в JavaScript обрезать свойства объекта?

У меня есть объект, как

{ prop_1 : val_1, prop_2 : val_2, prop_3 : val_3 , ..., prop_N : val_N } 

, и я хочу, чтобы удалить все свойства, которые не prop_i, prop_j или prop_K?

Что такое лучший способ сделать это, кроме «грубой силы» способ

var original = { prop_1 : val_1, prop_2 : val_2, prop_3 : val_3 , ..., prop_N : val_N }; 
var newguy = { prop_i : original.prop_i, prop_j : original.prop_j, prop_k : original.prop_k }; 
original = newguy; 

????

+2

вы можете «удалить» все остальные, но я должен думать, что создание нового с 3 явным реквизитом проще – dandavis

+1

Какой у вас вопрос с этим методом «грубой силы»? –

+0

, если вы используете buiilt в методе, он по-прежнему будет выполнять некоторую итерацию за сценой ... иначе он найдет свойство собственности? ... Я хотел бы знать это! ...... – repzero

ответ

1

Ну, вы можете сделать функцию, которая поможет вам в этом.

(function() { 
 
    'use strict'; 
 

 
    function copyOnly(obj, keysToPreserve) { 
 
    var result = {}; 
 
    for (var i = 0, length = keysToPreserve.length; i < length; ++i) { 
 
     var key = keysToPreserve[i]; 
 
     result[key] = obj[key]; 
 
    } 
 
    return result; 
 
    } 
 

 
    function copyExclude(obj, keysToExclude) { 
 
    var result = {}; 
 
    for (var key in obj) { 
 
     if (obj.hasOwnProperty(key) && keysToExclude.indexOf(key) === -1) { // -1 means key doesn't exist in keysToExclude 
 
     result[key] = obj[key]; 
 
     } 
 
    } 
 
    return result; 
 
    } 
 

 
    var original = { 
 
    a: '1', 
 
    b: '2', 
 
    c: '3', 
 
    d: '4', 
 
    e: '5' 
 
    }; 
 

 
    var toPreserve = ['a', 'b', 'c']; 
 
    var result1 = copyOnly(original, toPreserve); 
 
    
 
    var toExclude = ['d', 'e']; 
 
    var result2 = copyExclude(original, toExclude); 
 
    
 
    // result1 will have the same structure as result2 
 
    
 
    document.getElementById('result').innerHTML = 'result1 = ' + JSON.stringify(result1) + '\n' + 'result2 = ' + JSON.stringify(result2); 
 
})();
<pre id="result"></pre>

0

Это не-грубая сила. Он использует белый список, итерации над ними и копирует значения из «oldguy».

var oldguy = { 
 
    "prop_1": 1, 
 
    "prop_2": 2, 
 
    "prop_3": 3, 
 
    "prop_i": "i", 
 
    "prop_j": "j", 
 
    "prop_k": "k", 
 
    "prop_N": "N", 
 
    "prop_z": "Z" 
 
}; 
 

 
var newguy = {}; 
 

 
var keys_to_include = ['prop_i', 'prop_j', 'prop_k']; 
 

 
keys_to_include.forEach(function(k){ 
 
    newguy[k] = oldguy[k]; 
 
}); 
 

 
$('#output').html(JSON.stringify(newguy,null,' '));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<pre><code id="output"></code></pre>

+0

Вложенный цикл довольно медленный.было бы лучше кэшировать белый список в объект с истинными значениями, чтобы вы могли мгновенно проверить приемлемость без этой медленной вложенной итерации indexOf() на каждой внешней итерации. – dandavis

+0

ты абсолютно прав, @ дандавис. я изменил свой код, чтобы он был более эффективным и более точно соответствовал требованию OP –

+0

'forEach' не будет работать для старых браузеров и немного медленнее, чем цикл' for (var i = 0 ...) ' –

0

Простой .forEach и .indexOf над Object.keys к delete не-спички

function cleanExcept(o, whitelist) { 
    Object.keys(o).forEach(k => whitelist.indexOf(k) !== -1 ? 0 : delete o[k]); 
    return o; 
} 


var o = {foo: 'foo', bar: 'bar', fizz: 'fizz', buzz: 'buzz'}; 
cleanExcept(o, ['foo', 'fizz']); // Object {foo: "foo", fizz: "fizz"} 

Использование объекта кэш вместо .indexOf, согласно @dandavis

function cleanExcept(o, whitelist) { 
    var w = {}; 
    whitelist.forEach(k => w[k] = true); 
    Object.keys(o).forEach(k => w[k] ? 0 : delete o[k]); 
    return o; 
} 

Изменение этого кэша просто принять значения, которые вы хотите, и вернуть его (т.е. вы получите ссылку на новый объект)

function cleanExcept(o, whitelist) { 
    var w = {}; 
    whitelist.forEach(k => !(k in o) ? 0 : w[k] = o[k]); 
    return w; 
} 
+0

вложен цикл довольно медленный. было бы лучше кэшировать белый список в объект с истинными значениями, чтобы вы могли мгновенно проверить приемлемость без этой медленной вложенной итерации indexOf() на каждой внешней итерации. – dandavis

+0

@ dandavis не был уверен в этом, потому что вопрос заключается в том, почему кеширование нового объекта происходит только при создании нового объекта и возвращение –

+0

для достижения «белого списка» [k]? 0: delete o [k] 'вместо indexOf(), я думаю, вы можете сжимать« истину »кеша, чтобы сделать вывод, если вы хотите избежать создания объекта для игры или чего-то еще ... perf разница между поисками свойств и итерацией массива не является незначительной ... – dandavis

0

В ES6, вы можете написать

({prop_i, prop_j, prop_K}) => ({prop_i, prop_j, prop_K})(original) 

Это работает, определив функцию, которая разбирает аргументы в определенные значения свойств, и возвращает объект с этими значениями. Затем вызовите функцию на входном объекте.

См. One-liner to take some properties from object in ES 6.

Смежные вопросы