使用下划线展开功能
Unwind functionality with underscore
我需要mongodb的类似$unwind
的带有下划线的功能,这样
[{
groups: [{ name: 'test 1' }, { name: 'test 2' }],
id: 1
}]
成为
[{
id: 1,
group: {
name: 'test 1'
}
}, {
id: 1,
group: {
name: 'test 2'
}
}]
这可以用下划线完成吗?
您可以为目标字段中的每个元素映射一个新对象。例如,使用mixin并假设您想要一个类似_.unwind(object, field)
:的方法签名
_.mixin({
unwind: function(o, field) {
return _.map(o[field], function(val) {
var cloned = _.clone(o);
cloned[field] = val;
return cloned;
});
}
});
你会这样使用它:
_.unwind({
groups: [{ name: 'test 1' }, { name: 'test 2' }],
id: 1
}, 'groups');
和
- 小提琴http://jsfiddle.net/nikoshr/ag31ypeb/
- 片段
function log(obj) {
document.getElementById('logged').innerHTML+= '<p>'+JSON.stringify(obj)+'</p>';
}
_.mixin({
unwind: function(o, field) {
return _.map(o[field], function(val) {
var cloned = _.clone(o);
cloned[field] = val;
return cloned;
});
}
});
var o = { _id : 1, item : "ABC1", sizes: [ "S", "M", "L"] };
log(_.unwind(o, 'sizes'));
var g = {
groups: [{ name: 'test 1' }, { name: 'test 2' }],
id: 1
};
log(_.unwind(g, 'groups'));
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<div id='logged'></div>
如果你需要展开一个对象数组(更像mongodb的展开),你可以使用这个函数:
function unwindBy(arr, field){
return _.transform(arr, function(r, o){
Array.prototype.push.apply(r,
_.map(o[field], function(v){ return _.set(_.clone(o), field, v); })
);
}, []);
}
ES6允许重写它更短,并且不依赖于第三方libs:
function unwindBy(arr, f) {
return arr.reduce((r, o) => r.concat(o[f].map(v => ({ ...o, [f]: v }))), []);
}
示例:
unwindBy([{a:1, b:[1,2,3]}, {a:2, b:[3,4,5]}], 'b');
//[{a:1, b:1}, {a:1, b:2}, {a:1, b:3}, {a:2, b:3}, {a:2, b:4}, {a:2, b:5}]
如果您想添加目的地字段,可以使用下面的代码段来完成。这是根据@nikoshr的回答进行的修改。
function log(obj) {
document.getElementById('logged').innerHTML+= '<p>'+JSON.stringify(obj)+'</p>';
}
_.mixin({
unwind: function(o, field, toField) {
if(!toField) toField = field;
return _.map(o[field], function(val) {
var cloned = _.clone(o);
cloned[toField] = val;
return cloned;
});
}
});
var o = { _id : 1, item : "ABC1", sizes: [ "S", "M", "L"] };
log(_.unwind(o, 'sizes'));
var g = {
groups: [{ name: 'test 1' }, { name: 'test 2' }],
id: 1
};
log(_.unwind(g, 'groups', 'group'));
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<div id='logged'></div>
此函数将帮助展开json对象。
function flatten()
{
var objectData = [];
var arrayData = [];
var arrayDataKey = [];
var resultSet = [];
this.progress = function(doc){
objectData = [this.getObjectData(doc)];
this.unwindData(objectData,arrayData);
return resultSet;
}
this.getObjectData = function(doc,keyId){
var result = {};
var index = '';
if(keyId=='' || keyId==undefined){
keyId = '';
}
for(key in doc){
if(keyId==''){
index = key;
}else{
index = keyId+'.'+key;
}
if(Array.isArray(doc[key])===true){
if(typeof doc[key][0]=="object"){
arrayDataKey.push(key);
arrayData.push(doc[key]);
}else{
result[index] = doc[key];
}
}else if(typeof doc[key]=="object"){
if(doc[key]=="[object Object]"){
for (var k in data = this.getObjectData(doc[key],index)) { result[k] = data[k]; }
}else{
result[index] = doc[key];
}
}else{
result[index] = doc[key];
}
}
return result;
}
this.unwindData = function(doc,objectData){
for (var i = objectData.length - 1; i >= 0; i--) {
resultSet = [];
for(var key in doc){
for (var prop in objectData[i]) {
objectData[i][prop] = this.getObjectData(objectData[i][prop]);
for(var k in objectData[i][prop]){
var ke = arrayDataKey[i]+'.'+k;
doc[key][ke] = objectData[i][prop][k];
}
resultSet.push(doc[key]);
}
}
doc = resultSet;
}
}
}
var flat=新平面();flat.progress();
您可以查看lodash展开
示例用法:
const _ = require('lodash')
require('lodash-unwind')({ injected: true })
const data = [
{
a: [ 1, 2 ],
id: 'a1'
},
{
a: [ 3, 4 ],
id: 'a2'
}]
// Use unwind as part of lodash
const output = _.unwind(data, 'a')
// [
// {
// a: 1,
// id: 'a1'
// },
// {
// a: 2,
// id: 'a1'
// },
// {
// a: 3,
// id: 'a2'
// },
// {
// a: 4,
// id: 'a2'
// }
// ]
您可以尝试使用npm包展开数组查看一些示例用法。
您可以尝试npm包展开数组。
const { unwind } = require('unwind-array')
const result = unwind(
{
title: 'foobar',
topLevelArr: [1, 2]
},
{ path: 'topLevelArr' }
)
expect(result.length).to.be.equal(2)
expect(result).to.be.deep.equal([
{
title: 'foobar',
topLevelArr: 1
},
{
title: 'foobar',
topLevelArr: 2
}
])
相关文章:
- es6 相当于下划线查找位置
- 用空格替换下划线PHP
- 如何使用下划线js转换这些数据
- 带嵌套json的下划线js查找
- 如何逃离<>在javascript下划线模板中
- TinyMCE从MSWord粘贴的文本在所有文本下加下划线
- 使用lodash下划线基于键拆分jsonarray
- 在控制台中显示下划线变量
- 如何从另一个带下划线的数组中筛选带元素的数组
- 筛选下划线中的对象
- 在键值对中对求和值进行下划线
- 使用下划线将键和值的两个数组合并到一个对象中
- 如何将文件名中的斜线替换为下划线
- 如何在结果中添加下划线但不添加虚假值的情况下进行映射
- 下划线用句点扩展.旋转引号被删除,如何用引号获得它
- 如何将id数组与带下划线的对象数组嵌套属性进行比较
- 下划线模板不是不显示弹出框功能
- 循环中的挖空下划线循环会失去可观察的功能
- 使用下划线展开功能
- 内容替换功能:用下划线替换空格