Convert between row and column schemas(行模式与列模式之间的转换)¶
There are myriad ways to implement solutions in JavaScript. These examples highlight generic algorithms for common patterns seen in Slate applications. Many of these solutions use the built-in Lodash ↗ and Moment ↗ JavaScript libraries.
Transforming rows to columns¶
/**
* Transforms a row-oriented schema into a column-oriented schema (as returned by queries).
* Note: The first object of the array needs to contain all keys to be extracted (future columns).
* If the first object does not contain a superset of all keys, you can use the alternative commented code in the function.
*
* Before:
* [
* { foo : 1, bar : 4, baz : 7 },
* { bar : 5, baz : 8, foo : 2 },
* { foo : 3, baz : 9, bar : 6 }
* ]
*
* After:
* {
* foo : [1, 2, 3],
* bar : [4, 5, 6],
* baz : [7, 8, 9]
* }
*
*/
function transformRowSchemaToColumnSchema(arr, first_object_has_all_keys=true) {
if (_.isEmpty(arr)) {
return [];
}
var orderedKeys;
if(first_object_has_all_keys){
// In case the first object has all keys
orderedKeys = _.chain(arr)
.first()
.keys()
.sortBy()
.value();
} else {
// Alternative if not all objects have all keys :
orderedKeys = _.uniq(_.flatMap(arr, _.keys))
}
var sortKeysBy = function(obj) {
return _.zipObject(orderedKeys, _.map(orderedKeys, function(key) {
return obj[key];
}));
};
var indexToKeyMapping = _.reduce(orderedKeys, function(agg, key, i) {
agg[i] = key;
return agg;
}, {});
var arrayOfRowObjects = _.map(arr, sortKeysBy);
var arrayOfRowArrays = _.map(arrayOfRowObjects, function(obj) { return _.values(obj) });
var arrayOfColumnArrays = _.unzip(arrayOfRowArrays);
var objectOfColumnArrays = _.reduce(arrayOfColumnArrays, function(agg, columnArr, i) {
var key = indexToKeyMapping[i];
agg[key] = columnArr;
return agg;
}, {});
return objectOfColumnArrays;
}
var data = {{f_data}}
return transformRowSchemaToColumnSchema(data)
Transforming Columns to Rows¶
/**
* Transforms a column-oriented schema (as returned by queries) into a row-oriented schema (often for use in an {{#each}} loop)
*
* Before:
* {
* foo : [1, 2, 3],
* bar : [4, 5, 6],
* baz : [7, 8, 9]
* }
*
* After:
* [
* { foo : 1, bar : 4, baz : 7 },
* { foo : 2, bar : 5, baz : 8 },
* { foo : 3, bar : 6, baz : 9 }
* ]
*/
function transformColumnSchemaToRowSchema(data) {
var keys = _.keys(data);
var arrays = _.values(data);
// if `data` comes directly from a SQL query, remove the `._response` property
// delete data._response;
var arrayOfPropertyLists = _.zip.apply(_, arrays);
var arrayOfObjects = _.map(arrayOfPropertyLists, function(list) {
var obj = {};
_.each(keys, function(key, i) {
obj[key] = list[i];
});
return obj;
});
return arrayOfObjects;
}
var data = {{f_data}}
return transformColumnSchemaToRowSchema(data)
中文翻译¶
行模式与列模式之间的转换¶
在 JavaScript 中实现解决方案的方式多种多样。以下示例展示了 Slate 应用中常见模式的通用算法。其中许多解决方案使用了内置的 Lodash ↗ 和 Moment ↗ JavaScript 库。
将行模式转换为列模式¶
/**
* 将面向行的模式转换为面向列的模式(如查询返回的结果)。
* 注意:数组中的第一个对象需要包含所有待提取的键(即未来的列)。
* 如果第一个对象不包含所有键的超集,可以使用函数中注释的替代代码。
*
* 转换前:
* [
* { foo : 1, bar : 4, baz : 7 },
* { bar : 5, baz : 8, foo : 2 },
* { foo : 3, baz : 9, bar : 6 }
* ]
*
* 转换后:
* {
* foo : [1, 2, 3],
* bar : [4, 5, 6],
* baz : [7, 8, 9]
* }
*
*/
function transformRowSchemaToColumnSchema(arr, first_object_has_all_keys=true) {
if (_.isEmpty(arr)) {
return [];
}
var orderedKeys;
if(first_object_has_all_keys){
// 当第一个对象包含所有键时
orderedKeys = _.chain(arr)
.first()
.keys()
.sortBy()
.value();
} else {
// 当并非所有对象都包含所有键时的替代方案:
orderedKeys = _.uniq(_.flatMap(arr, _.keys))
}
var sortKeysBy = function(obj) {
return _.zipObject(orderedKeys, _.map(orderedKeys, function(key) {
return obj[key];
}));
};
var indexToKeyMapping = _.reduce(orderedKeys, function(agg, key, i) {
agg[i] = key;
return agg;
}, {});
var arrayOfRowObjects = _.map(arr, sortKeysBy);
var arrayOfRowArrays = _.map(arrayOfRowObjects, function(obj) { return _.values(obj) });
var arrayOfColumnArrays = _.unzip(arrayOfRowArrays);
var objectOfColumnArrays = _.reduce(arrayOfColumnArrays, function(agg, columnArr, i) {
var key = indexToKeyMapping[i];
agg[key] = columnArr;
return agg;
}, {});
return objectOfColumnArrays;
}
var data = {{f_data}}
return transformRowSchemaToColumnSchema(data)
将列模式转换为行模式¶
/**
* 将面向列的模式(如查询返回的结果)转换为面向行的模式(常用于 {{#each}} 循环中)
*
* 转换前:
* {
* foo : [1, 2, 3],
* bar : [4, 5, 6],
* baz : [7, 8, 9]
* }
*
* 转换后:
* [
* { foo : 1, bar : 4, baz : 7 },
* { foo : 2, bar : 5, baz : 8 },
* { foo : 3, bar : 6, baz : 9 }
* ]
*/
function transformColumnSchemaToRowSchema(data) {
var keys = _.keys(data);
var arrays = _.values(data);
// 如果 `data` 直接来自 SQL 查询,请移除 `._response` 属性
// delete data._response;
var arrayOfPropertyLists = _.zip.apply(_, arrays);
var arrayOfObjects = _.map(arrayOfPropertyLists, function(list) {
var obj = {};
_.each(keys, function(key, i) {
obj[key] = list[i];
});
return obj;
});
return arrayOfObjects;
}
var data = {{f_data}}
return transformColumnSchemaToRowSchema(data)