2015-04-30 4 views
0

У меня есть объект myObj как:Функциональные JS Установить все свойства на объекте

{ 
    0: true, 
    1: false, 
    2: false 
} 

Чтобы установить каждое значение true, я мог бы использовать цикл:

for (i in myObj) { 
    myObj[i] = true 
} 

Но есть функционал способ сделать это в javascript? Что-то вроде:

myOjb.fill(true) 
+1

Вы спрашиваете, как реализовать такую ​​функцию без использования 'for' цикл? Или существует ли такой метод изначально? Это не. Во многих из этих случаев '.reduce' является вашим другом. –

+1

Я бы сказал 'for (k in myObj) myObj [k] = true;', вероятно, самый простой, быстрый и сжатый способ сделать это, нет волшебной функции! – adeneo

+0

Я думаю, что я спрашиваю, какой лучший функциональный способ сделать это. – jcuenod

ответ

4

Object.keys (если доступно в вашей среде). Он перечисляет ключи на текущем объекте, пропускает свойства прототипа и тому подобное.

Вы бы просто сделать:

function fill(obj) { 
    Object.keys(obj).forEach(function (key) { 
    obj[key] = true; 
    }); 
} 

Если вы хотите получить действительно функциональный с ним, вы можете использовать сокращения и избежать побочных эффектов:

function fill(obj) { 
    return Object.keys(obj).reduce(function (p, key) { 
    p[key] = true; 
    return p; 
    }, {}); 
} 

Если вы хотите сохранить тот же прототип в качестве исходного объекта, предполагая, что вы работаете с простыми типами, у которых нет конструкторов без аргументов (количество объектов и массивов), вы можете использовать obj.constructor:

function fill(obj) { 
 
    return Object.keys(obj).reduce(function(p, key) { 
 
    p[key] = true; 
 
    return p; 
 
    }, new obj.constructor); 
 
} 
 

 
var filledObject = fill({ 
 
    bar: false, 
 
    baz: 3, 
 
    boo: 'test' 
 
}); 
 
var filledArray = fill([1, 2, 3, 4, false, 'test']); 
 

 
document.getElementById('obj').textContent = JSON.stringify(filledObject); 
 
document.getElementById('arr').textContent = JSON.stringify(filledArray); 
 

 
var evilSparseArray = [1, 2, 3]; 
 
evilSparseArray[19] = 4; 
 
document.getElementById('spa').textContent = JSON.stringify(fill(evilSparseArray));
<pre id="obj"></pre> 
 
<pre id="arr"></pre> 
 
<pre id="spa"></pre>

Обратите внимание, что это будет не корректно работают с редкими массивами, так как остальные ключи определены, но не имеют значимые данные.

+0

«уменьшить» на клавишах то, о чем я не думал - это довольно круто. – jcuenod

+0

Я думаю, что 'сокращение' является наиболее разумным функциональным способом этого. Это просто и должно быть приемлемо быстрым. Поведение «Object.keys» очень удобно здесь, так как оно работает и с массивами. – ssube

+0

Я предпочел бы использовать 'Object.create (Object.getPrototypeOf (this))' вместо 'new this.constructor' (у него нет никаких побочных эффектов, если мы делаем FP, не так ли?) – Bergi

0

Существует еще один способ сделать это, если у вас будет свой индекс в качестве значений

function convertObjectToValue (myObject, val) { 
    myObject.length = Object.keys(myObject).length; 
    return Array.prototype.slice.apply(myObject).map(function() { 
     return val; 
    }).reduce(function(obj, index, value) { 
     obj[index] = value; 
    },{}); 
    } 
+0

'[] .slice' не будет работать над объектом,' map (function (it) {return it;}) 'is no-op (и может быть оптимизирован), и это преобразует все в объект (даже если это началось как массив, на мой ответ также отмечен недостаток FelixKling). – ssube

+0

@ssube Я указал, что это не сработает, если у вас есть индекс как число, но да, ваш ответ - это просто другая истина, которая будет работать, если у вас есть 0-> n индексных чисел. –

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