Javascript 比较对象数组:Ramda方式

Javascript 比较对象数组:Ramda方式,javascript,ramda.js,Javascript,Ramda.js,有两个对象数组,第一个是 const blocks = [ { id: 1 }, { id: 2 }, { id: 3 }, ] 第二个是 const containers = [ { block: { id: 1 } }, { block: { id: 2 } }, { block: { id: 3 } }, ] 我想获取块数组,从中获取每个对象,并查找容器数组中是否有具有此类id的块。因此,如果至少一个id未找到,则我想中断循环并返回false,否则,如果找到的所

有两个对象数组,第一个是

const blocks = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
]
第二个是

const containers = [
  { block: { id: 1 } },
  { block: { id: 2 } },
  { block: { id: 3 } },
]
我想获取
数组,从中获取每个对象,并查找
容器
数组中是否有具有此类id的块。因此,如果至少一个id未找到,则我想中断循环并返回false,否则,如果找到的所有id都返回true

我曾尝试使用
.some()
函数来实现这一点,但当找不到id时,我无法中断循环

如果您能建议拉姆达如何完成这项工作,我将不胜感激


谢谢。

以非拉姆达方式,您可以将每个对象与其他项目进行比较,并使用深度检查

const
deep=id=>o=>
o&&typeof o=='object'&&(o.id==id | | object.values(o).some(deep(id)),
compare=(source,target)=>source.every({id})=>target.some(deep(id)),
blocks=[{id:1},{id:2},{id:3}],
容器=[{block:{id:1}},{block:{id:2}},{block:{id:3}]

日志(比较(块、容器))
您可以使用
equals()
方法

const块=[
{id:1},
{id:2},
{id:3},
]
常量容器=[
{block:{id:1}},
{block:{id:2}},
{block:{id:3}},
]
log(R.equals(containers.map(x=>x.block.id),blocks.map(x=>x.id))

您可以使用
R.differenceWith
执行此操作:

const块=[
{id:1},
{id:2},
{id:3},
];
常量容器=[
{block:{id:1}},
{block:{id:2}},
{block:{id:4}},
];
const diff=R.differenceWith((x,y)=>x.id==y.block.id);
常量不匹配=差异(块、容器)。长度>0;
控制台日志(不匹配)

没有特别的Ramda WayTM。Ramda是一个库、一个工具箱,或者在下划线的描述中是一个工具带。它是为了使某种风格的编码更易于在JS中读写而构建的。但它根本不是要规定如何编写代码

Ramda最大的目标是通过组合函数使构建应用程序变得更容易,从而确保诸如不变性和引用透明性等FP优点

因此,对于这个问题,我可以从以下内容开始:

const hasBlock=(容器)=>{
const id=containers.map(c=>c.block.id)
返回(block)=>id.includes(block.id)
}
const allContained=(容器)=>(块)=>
块。每个(hasBlock(容器))
后一个函数可以使用Ramda快速重写

const allContained=(容器)=>(块)=>
全部(hasBlock(容器)、块)
这简化为

const allContained=(容器)=>all(hasBlock(容器))
从那里到优雅的:

const allContained=compose(全部,hasBlock)
但是我没有看到任何直接简化的
hasBlock
。有时我可能会把它写成

consthasblock=(containers,id=containers.map(c=>c.block.id))=>
(block)=>id.includes(block.id)
但这只是为了满足内心对单一表达式函数体的渴望,而不是为了任何真正好的理由。它不会使代码变得更清晰,对某些读者来说,它可能会使代码更加晦涩

这就是我的结局:

const hasBlock=(容器)=>{
const id=containers.map(c=>c.block.id)
返回(block)=>id.includes(block.id)
}
const allContained=compose(全部,hasBlock)
const containers=[{block:{id:1},{block:{id:2},{block:{id:4}]
控制台日志(
allContained(containers)([{id:1},{id:2},{id:3}]),//=>false
allContained(容器)([{id:1},{id:2},{id:4}]),//=>true
allContained(容器)([{id:4},{id:1}]),//=>true
allContained(containers)([{id:42}]),//=>false
)


const{compose,all}=R
使用JS/Lodash/Ramda几乎可以以同样的方式实现这一点

JS/Lodash对
每个
一些
具有相同的精确方法,在Ramda中具有
所有
任何

const blocks=[{id:1},{id:2},{id:3}]
const containers=[{block:{id:1},{block:{id:2},{block:{id:3}]
const blocks2=[{id:1},{id:2},{id:3}]
const containers2=[{block:{id:4},{block:{id:2},{block:{id:3}]
让hasAllBlocks=(黑色,连续)=>
blks.every(b=>conts.some(c=>c.block.id==b.id))
让hasAllBlocksLD=(黑色,续)=>
_.every(blks,b=>.\uUsome(conts,c=>c.block.id==b.id))
让hasAllBlocksR=(黑色,续)=>
R.all(b=>R.any(c=>c.block.id===b.id,conts),blks)
log(hasAllBlocks(块、容器))//true
log(hasAllBlocks(blocks2,containers2))//false
log(hasAllBlocksLD(块、容器))//true
log(hasAllBlocksLD(blocks2,containers2))//false
log(hasAllBlocksR(块、容器))//true
log(hasAllBlocksR(blocks2,containers2))//false


那么你不应该使用
部分
,可能存在一个
全部
?你希望所有对象都是相同的还是至少其中一个?@MaheerAli我希望
数组中的所有对象在
容器中都有类似的块
array@appleapple有
.every()
函数,我已经用它实现了,但我不知道它是否是一个好的解决方案,我也想
Ramda
方法:)谢谢。我不想比较对象是否相等,我只想比较
id
参数。@CroaToa以便您可以将两者转换为id数组。然后比较。请参见编辑。