[英]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.