/ / Як перенести об’єкт у underscorejs - javascript, underscore.js, транспонірувати

Як транспортувати об'єкт в underscorejs - javascript, underscore.js, transpose

У JavaScript я намагаюся перетворити масив об’єктів з подібними клавішами:

[{"a":1,"b":2}, {"a":3,"b":4}, {"a":5,"b":6,"c":7}]

до об'єкта з масивом значень для кожного ключа:

{"a":[1,3,5], "b":[2,4,6], "c":[7]};

використовуючи underscore.js 1.4.2.

У мене є деякий робочий код нижче, але він відчувається довше і незграбніше, ніж просто писати вкладені для циклів.

Чи є більш елегантний спосіб зробити це підкресленням? Чи є щось просте, що мені не вистачає?

console.clear();

var input = [{"a":1,"b":2},{"a":3,"b":4},{"a":5,"b":6,"c":7}];
var expected = {"a":[1,3,5], "b":[2,4,6], "c":[7]};

// Ok, go
var output = _(input)
.chain()
// Get all object keys
.reduce(function(memo, obj) {
return memo.concat(_.keys(obj));
}, [])
// Get distinct object keys
.uniq()
// Get object key, values
.map(function(key) {
// Combine key value variables to an object
// ([key],[[value,value]]) -> {key: [value,value]}
return _.object(key,[
_(input)
.chain()
// Get this key"s values
.pluck(key)
// Filter out undefined
.compact()
.value()
]);
})
// Flatten array of objects to a single object
// [{key1: [value]}, {key2, [values]}] -> {key1: [values], key2: [values]}
.reduce(function(memo, obj) {
return _.extend(memo, obj);
}, {})
.value();

console.log(output);
console.log(expected);
console.log(_.isEqual(output, expected));

Дякую

Відповіді:

8 для відповіді № 1

Звуки, як ти хочеш zip для об’єктів. Це був би той аналог метод для об'єктів:

_.transpose = function(array) {
var keys = _.union.apply(_, _.map(array, _.keys)),
result = {};
for (var i=0, l=keys.length; i<l; i++) {
var key = keys[i];
result[key] = _.pluck(array, key);
}
return result;
};

Однак я б просто скористався

_.transpose = function(array) {
var result = {};
for (var i=0, l=array.length; i<l)
for (var prop in array[i])
if (prop in result)
result[prop].push(array[i][prop]);
else
result[prop] = [ array[i][prop] ];
return result;
};

без будь-якого підкреслення :-) Звичайно, ви можете використовувати деякі методи ітератора, це може виглядати так

_.reduce(array, function(map, obj) {
return _.reduce(obj, function(map, val, key) {
if (key in map)
map[key].push(val)
else
map[key] = [val];
return map;
}, map);
}, {});

1 для відповіді № 2

Ви можете використовувати lodash "s zipObject mehtod: https://lodash.com/docs#zipObject


0 для відповіді № 3

Вам потрібно 3 рядки лодаша:

_.merge.apply(null, _.union([{}], myArrayOfObjects, [function (a, b) {
return _.compact(_.flatten([a, b]));
}]))

Побачити док _.merge для отримання детальної інформації про те, що функція виконує.