I need to transmit some data, that has too many key-value pairs. As the keys are similar, I dont want to transmit them with each object.
Consider I have the following data:
[
{
x:11,
y:12
},{
x:21,
y:22
},{
x:31,
y:32
},{
x:41,
y:42
}
];
And I need the final output as
[ [x,y],[[11,12],[21,22],[31,32],[41,42]] ]
OR
[ [x,y],[11,12],[21,22],[31,32],[41,42] ]
On the other end, I should be able to convert back to its original form . It would be great if it can handle an additional key in some of the objects
I think I have seen lodash or underscore function for something close/similar to this, but I'm not able to find it right now.
NOTE: I don't know what the keys will be
Using Array#reduce
var arr = [{ x: 11, y: 12 }, { x: 21, y: 22 }, { x: 31, y: 32 }, { x: 41, y: 42 }]; var keys = Object.keys(arr[0]); var op = arr.reduce(function(a, b) { var arr = keys.reduce(function(x, y) { return x.concat([b[y]]); }, []) return a.concat([arr]); }, [keys]); //If all the objects are having identical keys! console.log(JSON.stringify(op));
A little more verbose way of doing it: [Edit: added the function to convert it back]
function convert(arr) { var retArr = [ [/* keys (retArr[0]) */], [/* values (retArr[1]) */] ] arr.forEach(function(obj){ // create new array for new sets of values retArr[1].push([]) // put all of the keys in the correct array for (var key in obj) { if (obj.hasOwnProperty(key)) { // does the key exist in the array yet? if (retArr[0].indexOf(key) === -1) { retArr[0].push(key) } // get last index of retArr[1] and push on the values retArr[1][retArr[1].length - 1].push(obj[key]) } } }) return retArr } function reConvert(arr) { var retArr = [] var keys = arr[0] arr[1].forEach(function(itemArr){ var obj = {} itemArr.forEach(function(item, i){ obj[keys[i]] = item }) retArr.push(obj) }) return retArr } var objArr = [ { x:11, y:12 },{ x:21, y:22 },{ x:31, y:32 },{ x:41, y:42 } ] var arrFromObj = convert(objArr) var objFromArr = reConvert(arrFromObj) console.log(arrFromObj) console.log(objFromArr)
A solution using Underscore.
First work out what the keys are:
var keys = _.chain(data)
.map(_.keys)
.flatten()
.uniq()
.value();
Then map across the data to pick out the value for each key:
var result = [
keys,
_.map(data, item => _.map(keys, key => item[key]))
];
and back again:
var thereAndBackAgain = _.map(result[1], item => _.omit(_.object(result[0], item), _.isUndefined));
Lodash's version of object is zipObject and omit using a predicate is omitBy :
var thereAndBackAgain = _.map(result[1], item => _.omitBy(_.zipObject(result[0], item), _.isUndefined));
var data = [ { x:11, y:12, aa: 9 },{ x:21, y:22 },{ x:31, y:32, z: 0 },{ x:41, y:42 } ]; var keys = _.chain(data) .map(_.keys) .flatten() .uniq() .value(); var result = [ keys, _.map(data, item => _.map(keys, key => item[key])) ]; var thereAndBackAgain = _.map(result[1], item => _.omit(_.object(result[0], item), _.isUndefined)); console.log(result) console.log(thereAndBackAgain)
<script src=" https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
Lodash v4.17.1
modify original
var modifiedOriginal = _.chain(original)
.map(_.keys)
.flatten()
.uniq()
.thru(function(header){
return _.concat(
[header],
_.map(original, function(item) {
return _.chain(item)
.defaults(_.zipObject(
header,
_.times(_.size(header), _.constant(undefined))
))
.pick(header)
.values()
.value()
})
);
})
.value();
modified back to original (keys order is not guarantee)
var backToOriginal = _.map(_.tail(modified), function(item) {
return _.chain(_.head(modified))
.zipObject(item)
.transform(function(result, val, key) {
if (!_.isUndefined(val)) {
result[key] = val;
}
})
.value();
});
JSFiddle code https://jsfiddle.net/wa8kaL5g/1/
In ES6 you can do it by reducing it with Object.values()
, and Object.keys()
. You can restore it using a combination of Array.prototype.map()
and Array.prototype.reduce()
:
const convertStructure = (data) => data.reduce((s, item) => { s[1].push(Object.values(item)); return s; }, [Object.keys(data[0]), []]); // all objects should be the same, so we can take the keys from the 1st object const restoreStructure = ([keys, data]) => data.map((item) => item.reduce((o, v, i) => { o[keys[i]] = v; return o; }, {})); const data = [{ x: 11, y: 12 }, { x: 21, y: 22 }, { x: 31, y: 32 }, { x: 41, y: 42 }]; const convertedStructure = convertStructure(data); console.log('convertedStructure:\\n', convertedStructure); const restoredStructure = restoreStructure(convertedStructure); console.log('restoredStructure:\\n', restoredStructure);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.