[英]Filter object base on an array with Ramda.js
let obj = {
tom: {
id: 0
},
david: {
id: 1
},
john: {
id: 2
}
}
let ids = [1, 2]
我想基于id过滤obj。
我想要的结果是
{david:{id:1},john:{id:2}}
因为上面的id是[1,2]。
我想用Ramda.js做到这一点。
请帮助我。
好吧,我很抱歉。
我做了这样的事情。
let obj2 = {}
ids.forEach((x) => {
obj2 += R.filter(y => y.id === x, obj)
})
obj = obj2
但是,这是不正确的。
而且我不想使用forEach。
我想做Ramda.js。
您只能使用Javascript
来执行此操作,首先可以使用要保留的ids
创建一个set(检查set是否具有元素为O(1)
)。 然后,您可以在原始object
上循环播放,并在key
集具有相关id
将key
及其value
添加到新object
:
let obj = { tom: {id: 0}, david: {id: 1}, john: {id: 2} } let ids = [1, 2]; const filterByIds = (obj, ids) => { let idsSet = new Set(ids); let filteredObj = {}; for (k in obj) { if (idsSet.has(obj[k].id)) filteredObj[k] = obj[k]; } return filteredObj; } console.log(filterByIds(obj, ids));
.as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;}
使用Ramda,您可以这样:
let obj = { tom: {id: 0}, david: {id: 1}, john: {id: 2} } let ids = [1, 2]; let idsSet = new Set(ids); const hasValidId = o => idsSet.has(o.id); let res = R.filter(hasValidId, obj); console.log(res);
.as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
如果您在此处阅读文档,那很容易
您可以通过使用Object.entries
并使用includes
来在纯JavaScript中进行操作:
let obj = { tom: { id: 0 }, david: { id: 1 }, john: { id: 2 } }; let ids = [1, 2]; let result = {}; Object.entries(obj).forEach(([name, { id }]) => { if (ids.includes(id)) { result[name] = { id: id }; } }); console.log(result);
一般来说,您应该努力使用对您有所帮助的数据结构,而不是不利于您的工作。
具有简化的数据结构,如下所示:
const obj = [
{id: 0, name: 'tom'},
{id: 1, name: 'david'},
{id: 2, name: 'john'}
]
您可以使用innerJoin
:
innerJoin((cur, id) => cur.id === id, obj, [1, 2])
如何将原始数据结构转换为简化的数据结构?
Ramda可以分为两个步骤:
使用toPairs
将您的对象拆分为键/值对的toPairs
:
{tom:{id:0}} ~> [['tom', {id: 0}]]
将每对映射到一个对象:
[['tom', {id: 0}]] ~> [{name: 'tom', id: 0}]
const obj = { tom: { id: 0 }, david: { id: 1 }, john: { id: 2 } } const convert = R.compose(R.map(([name, id]) => ({name, ...id})), R.toPairs); console.log(convert(obj))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
尝试这个:
let obj = { tom: { id: 0 }, david: { id: 1}, john: {id: 2} } let ids = [1, 2] ; let result = {} ; for ( var o in obj ) { if (ids.includes(obj[o].id)) result[o] = obj[o]; } console.log(result) ;
除非这是学习Ramda的练习,否则请注意要在Ramda中进行此操作的想法。 我是Ramda的主要作者之一,也是忠实的拥护者,但我需要强调的是,它只是一个工具包,在某些情况下无济于事。 如果有帮助,那很好,但这不是目标。
现在,我认为这可以为您提供帮助。 这就是我对Ramda的处理方式:
const matchIds = (obj, ids) => filter(propSatisfies(includes(__, ids), 'id'), obj) let obj = {tom: {id: 0}, david: {id: 1}, john: {id: 2}} let ids = [1, 2] console.log(matchIds(obj, ids))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> <script> const {__, filter, propSatisfies, includes} = R </script>
一种替代方法是,尤其是如果id列表比对象更不可能更改的方法是:
const matchIds = (ids) => filter(propSatisfies(includes(__, ids), 'id')) let obj = {tom: {id: 0}, david: {id: 1}, john: {id: 2}} let ids = [1, 2] console.log(matchIds(ids)(obj))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> <script> const {__, filter, propSatisfies, includes} = R </script>
有一些原因不喜欢占位符(' __
')。 如果您有这种感觉,可以用flip(includes)(ids)
替换includes(__, ids)
flip(includes)(ids)
。
我在这里不接受我的建议。 尽管我仍将propSatisfies
用作filter
,但这里不需要propSatisfies
。 一个简单的lambda就可以了:
const matchIds = (ids) => filter(({id}) => ids.includes(id))
至少一旦您习惯了部分应用程序的Ramda规范,它就会更干净,更易读。 ( filter
有两个参数:谓词函数和要使用它进行过滤的对象。由于我们只提供第一个参数,所以这给了我们一个期望第二个函数的函数。当我们用对象调用该结果函数时,就会进行过滤。)
我仍将使用Ramda的filter
的原因是,它没有直接内置于对象的内置版本。 Ramda提供了一种简单的方法来编写一次性对象过滤。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.