簡體   English   中英

如何在給定的對象結構中使用Ramda執行嵌套更新?

[英]How to perform a nested update using Ramda in the given object structure?

假設遵循對象,在給定的應用程序,標准ID和數據的條件下,如何使用Ramda在標准中執行嵌套更新?

const application = {
  id: 'a1',
  features: [
    {
      id: 'f1',
      criterias: [
        { id: 'c1' }
      ]
    },
    {
      id: 'f2',
      criterias: [
        { id: 'c2' },
        { id: 'c3' }
      ]
    }
  ]
}

該函數將如下所示:

const updateCriteria = (application, criteriaId, data) => // magic...

updateCriteria(application, 'c2', { name: 'foo' })

// output: {
//  id: 'a1',
//  features: [
//    {
//      id: 'f1',
//      criterias: [
//        { id: 'c1' }
//      ]
//    },
//    {
//      id: 'f2',
//      criterias: [
//        { id: 'c2', name: 'foo' },
//        { id: 'c3' }
//      ]
//    }
//  ]
// }

鏡頭可能是您最好的選擇。 Ramda具有通用的lens函數,並具有對象屬性( lensProp ),數組索引( lensIndex )和更深的path( lensPath )的lensPath ,但不包括通過以下方法在數組中查找匹配值的函數: ID。 但是,制造我們自己並不難。

通過將兩個函數傳遞給lens來制作lens :一個獲取對象並獲取相應值的吸氣劑,以及獲取新值和對象並返回對象的更新版本的設定器。

在這里,我們編寫lensMatch ,它在給定屬性名稱與提供的值匹配的數組中查找或設置值。 lensId只是將'id'傳遞給lensMatch以獲取一個函數,該函數將獲取id值並返回一個鏡頭。

使用任何鏡頭,我們都有viewsetover函數,分別獲取,設置和更新值。

我們可以這樣使用idLens

const data = [{id: 'a'}, {id: 'b'}, {id: 'c'}]

view (idLens ('b'), data) 
  //=> {id: 'b'}
set  (idLens ('b'), 'foo', data) 
  //=> [ {id: 'a'}, 'foo', {id: 'c'} ]
over (idLens ('b'), merge ({name: 'foo'}), data)
  //=> [ {id: 'a'}, {id: 'b', name: 'foo}, {id: 'c'} ]

因此,對於您的問題,我們可以這樣寫:

 const lensMatch = (propName) => (key) => lens ( find ( propEq (propName, key) ) , (val, arr, idx = findIndex (propEq (propName, key), arr)) => update (idx > -1 ? idx : length (arr), val, arr) ) const lensId = lensMatch ('id') const updateCriteria = (featureId, criteriaId, data, application) => over ( compose ( lensProp ('features') , lensId (featureId) , lensProp ('criterias') , lensId (criteriaId) ) , merge (data) , application ) const application = {id: 'a1', features: [{id: 'f1', criterias: [{ id: 'c1' }]}, {id: 'f2', criterias: [{ id: 'c2' }, { id: 'c3' }]}]} const newApp = updateCriteria ('f2', 'c2', {name: 'foo'}, application) console.log(newApp) 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> <script> const {lens, find, propEq, findIndex, update, length, view, set, over, compose, lensProp, merge} = R </script> 

但這前提是您知道featureId 如果您需要同時找到featureId和帶有內部ID的嵌套對象,則可以為此編寫一個更復雜的鏡頭,但重量會更大。


一個小注釋:“標准”已經是復數形式,因此“標准”很奇怪。 單數是“標准”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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