Javascript 映射添加/减少具有相同索引的两个数组对象
我有两个数组对象,如下所示:Javascript 映射添加/减少具有相同索引的两个数组对象,javascript,arrays,json,ecmascript-6,functional-programming,Javascript,Arrays,Json,Ecmascript 6,Functional Programming,我有两个数组对象,如下所示: var arr1 = [ { name: 1, value: 10 }, { name: 2, value: 15 } ] var arr2 = [ { name: 3, value: 5 }, { name: 4, value: 3 } ] formatData = ar
var arr1 = [
{
name: 1,
value: 10
},
{
name: 2,
value: 15
}
]
var arr2 = [
{
name: 3,
value: 5
},
{
name: 4,
value: 3
}
]
formatData = arr1.map((row, index) => ({
itemLabel: arr1.name,
itemValue: arr1.value - arr2[index].value
}))
我想重新定义键并使用相同的索引减少每个数据
输出:
var arr1 = [
{
itemLabel: 1,
itemValue: 5
},
{
itemLabel: 2,
itemValue: 12
}
]
我现在的工作如下:
var arr1 = [
{
name: 1,
value: 10
},
{
name: 2,
value: 15
}
]
var arr2 = [
{
name: 3,
value: 5
},
{
name: 4,
value: 3
}
]
formatData = arr1.map((row, index) => ({
itemLabel: arr1.name,
itemValue: arr1.value - arr2[index].value
}))
有没有更好的解决办法 您的代码很好,也可以使用递归:
var arr1=[{
姓名:1,,
数值:10
}, {
姓名:2,,
价值:15
}];
var arr2=[{
姓名:3,,
价值:5
}, {
姓名:4,,
价值:3
}]
const createObject=(arr1、arr2、ret=[])=>{
if(arr1.length!==arr2.length){
throw(“数组的长度应该相同。”)
}
常数项={
itemLabel:arr1[0]。名称,
itemValue:arr1[0]。值-arr2[0]。值
};
如果(arr1.length==0){
返回ret;
};
返回createObject(arr1.slice(1)、arr2.slice(1)、ret.concat(item));
}
log(createObject(arr1,arr2))代码>要使您的解决方案更实用,您需要将匿名函数更改为纯(匿名)函数
纯函数是指给定相同的输入,总是返回相同的输出的函数
匿名函数取决于可变变量arr1
和arr2
。这意味着它取决于系统状态。因此,它不符合纯函数规则
下面可能不是最好的实现,但我希望它能给你一个想法
让我们让它变得纯净
为了使它更纯粹,我们可以将变量作为参数传递到函数中
const mapWithObject = (obj2, obj1, index) => ({
itemLabel: obj1.name,
itemValue: obj1.value - obj2[index].value
})
// example call
const result = mapWithObject(arr2, arr1[0], 0)
好的,但是现在这个函数不再适合map
,因为它需要3个参数而不是2
让我们开始吧
完整代码
const arr1=[{
姓名:1,,
数值:10
},
{
姓名:2,,
价值:15
}
]
常数arr2=[{
姓名:3,,
价值:5
},
{
姓名:4,,
价值:3
}
]
常量mapWithObject=obj2=>(obj1,索引)=>({
itemLabel:obj1.name,
itemValue:obj1.value-obj2[index].value
})
常量mapObject_with_arr2=mapWithObject(arr2)
常量mappedObject=arr1.map(带arr2的mappedObject_)
console.log(mappedObject)
如果您不太关心性能,但想进一步分离您的顾虑,您可以使用以下方法:
- 定义在
arr1
和arr2
[a, b, c] + [1, 2, 3] -> [ [ a, 1 ], [ b, 2 ], [ c, 3 ] ]
- 定义一个明确显示两个对象合并策略的函数
{ a: 1, b: 10 } + { a: 2, b: 20 } -> { a: 1, b: -10 }
- 定义组成这两个数组的简单帮助器,以便可以传递原始数组,并在一次函数调用中返回所需的输出
下面是一个例子:
var arr1=[{name:1,value:10},{name:2,value:15}],arr2=[{name:3,value:5},{name:4,value:3}];
//这是一种非常通用的方法,它将两个
//成对数组中的数组。把它放在你的肚子里
//你可以在任何地方使用它
常量对=(arr1,arr2)=>Array.from(
{length:Math.max(arr1.length,arr2.length)},
(u,i)=>[arr1[i],arr2[i]]
);
//这定义了两个对象的合并策略。
//理想情况下,你应该给它一个更好的名字,基于
//关于对象代表什么
常数合并=
(基本,外部)=>({
itemLabel:base.name,
itemValue:base.value-ext.value
});
//这是一个“应用”合并方法的助手
//指向两个项目的数组。
const mergePair=([base,ext])=>merge(base,ext);
//另一个由'pairs'和'mergePair'组成的助手
//允许您传递原始数据。
const mergeArrays=(arr1,arr2)=>pairs(arr1,arr2).map(mergePair);
log(合并数组(arr1,arr2))代码>一人军队
一个简单的递归程序,在一个函数中处理所有事情。这里有一个明显的混合关注点,它损害了函数的整体可读性。下面我们将看到一种解决这个问题的方法
const main=([x,…xs],[y,…ys])=>
x==未定义| | y==未定义
? []
:[{itemlab:x.name,itemValue:x.value-y.value}].concat(main(xs,ys))
常数arr1=
[{name:1,value:10},{name:2,value:15}]
常数arr2=
[{name:3,value:5},{name:4,value:3}]
console.log(主(arr1、arr2))
//[{itemLabel:1,itemValue:5},
//{itemLabel:2,itemValue:12}]
您当前的解决方案有什么问题?您所说的“更实用”是什么意思?我认为他的意思是“有更好的解决方案吗”您的map
调用已经是一个纯函数了。它不会改变任何现有对象或造成任何副作用。它的功能再强大不过了。你可以用另一种方法,但不会更好。你所做的是更好的解决方案,嗯,我明白了。有没有更好的解决办法!?在某种程度上,阅读这个答案的信息非常丰富,它使用了与我的答案相同的方法,但更清晰,使用了正确的术语,而且写得更好;)我已经了解到我的对
被称为zip
,我的merge
本质上是concat
,我的助手“apply”
实际上可以被一个literalapply
函数代替。