[英]How to preload a Ramda curried function with item of an Array?
我有tagsList
其具有約20的標簽,和termIds
為不超過3的標簽ID的陣列。
我正在嘗試在tagsList中找到與termIds中的ID匹配的標簽,然后設置其邊界。 尋求避免循環和面向對象的編程,轉而使用Ramda curry的功能編程解決方案。
tagsList中的標簽如下所示:
{
term: 'hi',
id: 123
}
termIds可能看起來像[123, 345, 678]
123、345、678 [123, 345, 678]
當我找到一個匹配的ID時,給該標簽一個新的鍵border1:true
, border2:true
等。
有一個標簽列表,我還有另一個termIds數組,目標是查看tagsList中的任何標簽是否具有與termIds匹配的ID。 如果是這樣,給它一個border1,如果有2,那么第二個得到border2,最后3個得到border 3。
const checkId = _.curry((term_id, tag) => {
if (tag.id === term_id) {
console.log('match found!', tag)
}
});
const matchId = checkId(termIds);
const coloredTags = R.map(matchId, tagsList);
console.log('coloredTags', coloredTags)
return tagsList;
但是,這不起作用,因為我將整個termIds數組預加載到checkId
函數中。 取而代之的是,我想預加載單個項目。
接下來,我嘗試了我認為可以解決的問題,但遇到一個奇怪的錯誤:
const matchId = R.forEach(checkId, termIds);
我認為,沒有Ramda的純JS就足夠了。 您只需要一張地圖:
var tagsList = [{term: 'hi', id: 123}, {term: 'ho', id: 152}, {term: 'hu', id: 345}, {term: 'ha', id: 72}]; var termIds = [123, 345, 678]; var i = 1; var results = tagsList.map(x => { if (termIds.indexOf(x.id) !== -1) x["border"+ (i++)] = true; return x; }); console.log(results);
這似乎是一種合理的方法:
R.map(tag => {
const index = R.indexOf(tag.id, termIds);
return (index > -1) ? R.assoc('border' + (index + 1), true, tag) : tag
})(tagsList);
//=> [
// {id: 123, term: "hi", border1: true},
// {id: 152, term: "ho"},
// {id: 345, term: "hu", border2: true},
// {id: 72, term: "ha"}
// ]
盡管可以通過足夠的努力使它成為無分的,但它的可讀性可能會大大降低。
您可以在Ramda REPL上看到這一點。
如果要將其變成可重用的函數,可以這樣進行:
const addBorders = R.curry((terms, tags) => R.map(tag => {
const index = R.indexOf(tag.id, terms);
return (index > -1) ? R.assoc('border' + (index + 1), true, tag) : tag
})(tags))
addBorders(termIds, tagsList)
(調用curry
是addBorders(termIds)
一種習慣。這意味着您可以調用addBorders(termIds)
並獲取正在尋找標簽的可重用函數。如果不需要,可以跳過curry
包裝器。)
該版本也在Ramda REPL上 。
嗯,我終於明白了,我不得不第二次對邏輯進行討論:
const matchId = R.curry((tag, term_id) => {
if (tag.id === Number(term_id)) {
console.log('match found!', tag)
}
});
const curried = R.curry((termIds, tag) => {
return R.map(matchId(tag), termIds);
});
const coloredTags = R.map(curried(termIds), tagsList);
console.log('coloredTags', coloredTags)
return tagsList;
因此,在coloredTags
行中,來自tagsLists的標簽進入了curried(termIds)。 Ramda函數從右到左接受參數。
curried(termIds)
已經預裝了termIds數組。 因此,接下來在const curried =
curried const curried =
行中,將termIds數組和單個標簽放入其中,並將該標簽發送到下一個咖喱函數matchId
,還將termIds
數組放置在R.map
。 Ramda列表函數接受數據數組作為正確的參數。
最后,在matchId
我可以進行檢查!
更新
因此,以上內容回答了我提出的關於如何從Array中咖喱物品的問題。 但是,這導致了我的應用程序中的錯誤。 由於termIds
數組最多可容納3個項目,因此coloredTags R.map
將最多運行3次,並在我的tagsList中創建重復的標簽。
因此,僅出於完整性考慮,這就是我解決問題的方式,它簡單得多,並且不需要使用double curried函數。
const setTagColors = (tagsList, state) => {
const setBorder = (tag) => {
if (tag.id === Number(state.term_id_1)) {
tag.border1 = true;
} else if (tag.id === Number(state.term_id_2)) {
tag.border2 = true;
} else if (tag.id === Number(state.term_id_3)) {
tag.border3 = true;
}
return tag;
};
const coloredTags = R.map(setBorder, tagsList);
return state.term_id_1 ? coloredTags : tagsList;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.