Ecmascript 6 使用map&;将两个列表合并为一个;箭头函数
我有两个列表,我想将它们组合起来,以便将它们填充到一个列表中。我知道使用嵌套for循环可以实现这一点,但我正试图避免for循环,因为我必须循环大量的数据。我想使用箭头函数或其他任何东西来实现这一点 列表一:Ecmascript 6 使用map&;将两个列表合并为一个;箭头函数,ecmascript-6,arrow-functions,Ecmascript 6,Arrow Functions,我有两个列表,我想将它们组合起来,以便将它们填充到一个列表中。我知道使用嵌套for循环可以实现这一点,但我正试图避免for循环,因为我必须循环大量的数据。我想使用箭头函数或其他任何东西来实现这一点 列表一: let fields = [ { field: "Name", fieldType: "Text" }, { field: "Active__c", fieldType: "Boolean" },
let fields = [
{
field: "Name",
fieldType: "Text"
},
{
field: "Active__c",
fieldType: "Boolean"
},
{
field: "Contact",
fieldType: "Relationship"
}
];
let rows = [
{
contact: {
Name: "Joe",
Active__c: true,
Contact: "SomeContact"
}
},
{
contact: {
Name: "Rachel",
Active__c: true
}
},
{
contact: {
Name: "Ross",
Active__c: true
}
},
{
contact: {
Name: "Monica",
Active__c: true
}
}
];
let output = rows.map(row => ({
id: row.Id,
data: {
value: fields.map(field => (row.contact[field.field])),
field: fields.map(field => field.field)
}
}));
[
{
"data": {
"value": [
"Joe",
true,
"SomeContact"
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Rachel",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Ross",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Monica",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
}
]
[
data : [
[
{
field : "Name",
type: "Text",
value : "Joe"
},
{
field : "Active__c",
type: "Boolean",
value : true
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact"
}
],
[
{
field : "Name",
type: "Text",
value : "Rachel"
},
{
field : "Active__c",
type: "Boolean",
value : false
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact Two"
}
],
[
...
],
[
...
]
]
]
列表二:
let fields = [
{
field: "Name",
fieldType: "Text"
},
{
field: "Active__c",
fieldType: "Boolean"
},
{
field: "Contact",
fieldType: "Relationship"
}
];
let rows = [
{
contact: {
Name: "Joe",
Active__c: true,
Contact: "SomeContact"
}
},
{
contact: {
Name: "Rachel",
Active__c: true
}
},
{
contact: {
Name: "Ross",
Active__c: true
}
},
{
contact: {
Name: "Monica",
Active__c: true
}
}
];
let output = rows.map(row => ({
id: row.Id,
data: {
value: fields.map(field => (row.contact[field.field])),
field: fields.map(field => field.field)
}
}));
[
{
"data": {
"value": [
"Joe",
true,
"SomeContact"
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Rachel",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Ross",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Monica",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
}
]
[
data : [
[
{
field : "Name",
type: "Text",
value : "Joe"
},
{
field : "Active__c",
type: "Boolean",
value : true
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact"
}
],
[
{
field : "Name",
type: "Text",
value : "Rachel"
},
{
field : "Active__c",
type: "Boolean",
value : false
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact Two"
}
],
[
...
],
[
...
]
]
]
当前代码:
let fields = [
{
field: "Name",
fieldType: "Text"
},
{
field: "Active__c",
fieldType: "Boolean"
},
{
field: "Contact",
fieldType: "Relationship"
}
];
let rows = [
{
contact: {
Name: "Joe",
Active__c: true,
Contact: "SomeContact"
}
},
{
contact: {
Name: "Rachel",
Active__c: true
}
},
{
contact: {
Name: "Ross",
Active__c: true
}
},
{
contact: {
Name: "Monica",
Active__c: true
}
}
];
let output = rows.map(row => ({
id: row.Id,
data: {
value: fields.map(field => (row.contact[field.field])),
field: fields.map(field => field.field)
}
}));
[
{
"data": {
"value": [
"Joe",
true,
"SomeContact"
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Rachel",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Ross",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Monica",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
}
]
[
data : [
[
{
field : "Name",
type: "Text",
value : "Joe"
},
{
field : "Active__c",
type: "Boolean",
value : true
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact"
}
],
[
{
field : "Name",
type: "Text",
value : "Rachel"
},
{
field : "Active__c",
type: "Boolean",
value : false
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact Two"
}
],
[
...
],
[
...
]
]
]
此代码的输出:
let fields = [
{
field: "Name",
fieldType: "Text"
},
{
field: "Active__c",
fieldType: "Boolean"
},
{
field: "Contact",
fieldType: "Relationship"
}
];
let rows = [
{
contact: {
Name: "Joe",
Active__c: true,
Contact: "SomeContact"
}
},
{
contact: {
Name: "Rachel",
Active__c: true
}
},
{
contact: {
Name: "Ross",
Active__c: true
}
},
{
contact: {
Name: "Monica",
Active__c: true
}
}
];
let output = rows.map(row => ({
id: row.Id,
data: {
value: fields.map(field => (row.contact[field.field])),
field: fields.map(field => field.field)
}
}));
[
{
"data": {
"value": [
"Joe",
true,
"SomeContact"
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Rachel",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Ross",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Monica",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
}
]
[
data : [
[
{
field : "Name",
type: "Text",
value : "Joe"
},
{
field : "Active__c",
type: "Boolean",
value : true
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact"
}
],
[
{
field : "Name",
type: "Text",
value : "Rachel"
},
{
field : "Active__c",
type: "Boolean",
value : false
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact Two"
}
],
[
...
],
[
...
]
]
]
所需输出:
let fields = [
{
field: "Name",
fieldType: "Text"
},
{
field: "Active__c",
fieldType: "Boolean"
},
{
field: "Contact",
fieldType: "Relationship"
}
];
let rows = [
{
contact: {
Name: "Joe",
Active__c: true,
Contact: "SomeContact"
}
},
{
contact: {
Name: "Rachel",
Active__c: true
}
},
{
contact: {
Name: "Ross",
Active__c: true
}
},
{
contact: {
Name: "Monica",
Active__c: true
}
}
];
let output = rows.map(row => ({
id: row.Id,
data: {
value: fields.map(field => (row.contact[field.field])),
field: fields.map(field => field.field)
}
}));
[
{
"data": {
"value": [
"Joe",
true,
"SomeContact"
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Rachel",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Ross",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
},
{
"data": {
"value": [
"Monica",
true,
null
],
"field": [
"Name",
"Active__c",
"Contact"
]
}
}
]
[
data : [
[
{
field : "Name",
type: "Text",
value : "Joe"
},
{
field : "Active__c",
type: "Boolean",
value : true
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact"
}
],
[
{
field : "Name",
type: "Text",
value : "Rachel"
},
{
field : "Active__c",
type: "Boolean",
value : false
},
{
field : "Contact",
type: "Relationship",
value : "SomeContact Two"
}
],
[
...
],
[
...
]
]
]
如何实现这一点?数据属性是唯一的,必须在创建对象(而不是所需输出中的数组)时内联定义它。您必须将
字段
数组映射到行
的每个元素,然后用行
数据填充每个字段
数据(如果存在)。此外,我在行
数组中的任何行对象上都看不到Id
字段。如果字段不存在,此代码将设置null
:
let输出={
数据:rows.map({contact})=>
fields.map({field,fieldType:type})=>({
领域
类型,
值:联系人中的字段?联系人[字段]:null//如果联系人没有字段,则设置null
}))
)
}
运行此代码段以查看结果:
let字段=[
{
字段:“名称”,
字段类型:“文本”
},
{
字段:“活动\uuuu c”,
字段类型:“布尔”
},
{
字段:“联系人”,
字段类型:“关系”
}
];
让行=[
{
联系人:{
姓名:“乔”,
主动的c:是的,
联系人:“SomeContact”
}
},
{
联系人:{
姓名:“瑞秋”,
活动的\uuu\c:正确
}
},
{
联系人:{
姓名:“罗斯”,
活动的\uuu\c:正确
}
},
{
联系人:{
姓名:“莫妮卡”,
活动的\uuu\c:正确
}
}
];
让输出={
数据:rows.map({contact})=>
fields.map({field,fieldType:type})=>({
领域
类型,
值:联系人中的字段?联系人[字段]:空
}))
)
}
document.getElementById('output').appendChild(
document.createTextNode(JSON.stringify(输出,null,2))
);代码>
你应该担心的不是循环,而是算法的复杂性。如我所见,在行中有可选字段
,并且在所需的输出中没有要求null
值。因此,我会提出一个不同于Christos Lytras的解决方案。
在每一行中迭代字段
,迭代将为您提供O(N^M)
复杂性。其中,N
-是行.长度
,M
是字段.长度
。这可能是个坏主意。以下代码将为您提供线性复杂度O(N+M)
。其中M
仍然是字段。length
和N
是行中每行的字段数之和,这听起来比O(N^M)
更可怕,但是,如果您有可选字段,它将为您节省一笔财富-请在代码段输出中查找调用X次的
//准备字典,稍后字段\u dict[field]将具有O(1)复杂性
const fields_dict=fields.reduce((acc,{field,fieldType})=>{
acc[字段]=字段类型
返回acc
}, {})
让输出2={
数据:rows.map({contact})=>
Object.keys(contact.map)(field=>({//仅对现有字段进行迭代
领域
类型:字段\u dict[字段],
值:联系人[字段],
}))
)
}
顺便说一下
我知道使用嵌套for循环可以实现这一点,但我试图避免for循环,因为我必须在函数上循环大量的数据
…即使在现代浏览器中,循环的性能也优于map()
、reduce()
和Co,反之亦然
请看片段中的计时。至少在我的环境中,for
version的速度是map
version(第一次运行时)的两倍。当然,按照JIT编译器的标准,此时的代码绝不是热门的,所以浏览器没有对代码进行优化。JIT编译后,性能上的差异变得可以忽略不计(按几次运行代码片段
)。不过,循环速度更快,至少在第一次运行时是如此
但若您不想测试代码的性能,那个么就不要费心对其进行微优化。最好考虑算法的复杂性。而且,是的,使用功能性风格——它更易于书写和阅读。
let字段=[
{字段:“名称”,字段类型:“文本”},
{field:“Active_u_c”,fieldType:“Boolean”},
{字段:“联系人”,字段类型:“关系”},
{字段:“extra1”,字段类型:“something”},
{字段:“extra2”,字段类型:“something”},
{field:“extra3”,fieldType:“something”},
{field:“extra4”,fieldType:“something”},
];
让行=[
{contact:{Name:“Joe”,Active_uc:true,contact:“SomeContact”},
{联系人:{姓名:“Rachel”,活动{u c:true}},
{联系人:{Name:“Ross”,Active_uc:true}},
{联系人:{姓名:“Monica”,活动{u c:true}},
{联系人:{姓名:“Monica”,活动{u c:true}},
{联系人:{姓名:“Monica”,活动{u c:true}},
{联系人:{姓名:“Monica”,活动{u c:true}},
{联系人:{姓名:“Monica”,活动{u c:true}},
{联系人:{姓名:“Monica”,活动{u c:true}},
{联系人:{姓名:“Monica”,活动{u c:true}},
];
让我
i=0
console.time(“Christos Lytras版本”)
让输出1={
数据:rows.map({contact})=>
fields.map({field,fieldType:type})=>(i++{
领域
类型,
值:联系人中的字段?联系人[字段]:空
}))
)
}
console.timeEnd(“Christos Lytras版本”)
log(`called${i}times`)
i=0
设j=0
控制台时间(“功能版本”)
const fields_dict=fields.reduce((acc,{field,fieldType})=>{i++,acc[field]=fieldType;返回acc},{})
让输出2={
数据:r