簡體   English   中英

如何使用數組項預加載Ramda咖喱函數?

[英]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:trueborder2: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)

(調用curryaddBorders(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM