簡體   English   中英

更新 object 值 Ramda

[英]Update object value Ramda

In previous question I tried to group arrays by parent ids and then remove them from each object - Group arrays by parent ids object Ramda .

但現在我有一個新問題。 例如,我想用 id 12 更新 object 中的標題。

我的數據 model:

const stuff = {
  "31": [
    {
      "id": "11",
      "title": "ramda heeeelp"
    },
    {
      "id": "12",
      "title": "ramda 123"
    }
  ],
  "33": [
    {
      "id": "3",
      "title": "..."
    }
  ],
  "4321": [
    {
      "id": "1",
      "title": "hello world"
    }
  ]
}

嘗試:

const alter = (id, key, value) => pipe(
  values,
  flatten,
  update(...) // <= end of my attempts
  // then group again
)

alter('12', 'title', 'new heading 123')(stuff)

您可以在此處使用鏡頭

  1. 結束: https://ramdajs.com/docs/#over
  2. 設置: https://ramdajs.com/docs/#set

 const titleLens = R.curry((key, id, data) => R.lensPath([ key, R.findIndex(R.whereEq({ id }), R.propOr([], key, data)), 'title' ])); // ---- const stuff = { "31": [ { "id": "11", "title": "ramda heeeelp" }, { "id": "12", "title": "ramda 123" } ], "33": [ { "id": "3", "title": "..." } ], "4321": [ { "id": "1", "title": "hello world" } ] } const title3111 = titleLens('31', '11', stuff); const result = R.set(title3111, 'DID RAMDA HELP YOU?', stuff); console.log('result', result);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>

我認為這最好用定制lens來完成。 在這里,我編寫了一個鏡頭創建器 ( idInObjLens ),它專注於具有正確 id 的 object,無論它屬於哪個組。然后我編寫myLens來接受一個 id 和一個屬性名稱,並返回一個專注於該屬性的鏡頭object。

有了這些,我們可以使用 Ramda 的viewsetover來查看值、設置值或使用 function 更新值:

 const idInObjLens = (id) => lens ( (obj) => { let index = -1 const child = find (value => (index = findIndex (propEq ('id', id), value)) > -1, values (obj) ) if (child) return child [index] }, (val, obj) => { let index = -1 const [key, value] = find (([key, value]) => (index = findIndex (propEq ('id', id), value)) > -1, toPairs (obj) ) return assoc (key, update (index, val, value), obj) }, ) const myLens = (id, key) => compose (idInObjLens (id), lensProp (key)) const stuff = {"31": [{"id": "11", "title": "ramda heeeelp"}, {"id": "12", "title": "ramda 123"}], "33": [{"id": "3", "title": "..."}], "4321": [{"id": "1", "title": "hello world"}]}; [ view (myLens ('12', 'title'), stuff), set (myLens ('3', 'title'), 'new heading 123', stuff), over (myLens ('1', 'title'), toUpper, stuff), ].forEach (x => console.log (x))
 .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.26.1/ramda.js"></script> <script>const {lens, find, findIndex, propEq, values, toPairs, assoc, update, compose, lensProp, view, set, over, toUpper } = R</script>

請注意,只有當該 id 實際存在時, setover才會起作用。 您可能需要先使用view進行檢查。

myLens很簡單; 這就是鏡頭構圖的工作原理。 (請注意,它似乎從常規撰寫中倒流; 技術原因很有趣,但超出了 SO 答案的 scope。)但idInObjLens更復雜。 與所有鏡頭一樣,它需要一個 getter 和一個 setter。 他們兩個同時找到 object 鍵,該鍵包含與該 object 鍵關聯的數組中具有該鍵的 id 和索引的項目。 getter 只是簡單地返回值。 setter 使用assoc更新外部 object 並update以更新其中的數組。 所有其他嵌套對象都通過引用簡單地返回。

這不是值得驕傲的代碼。 它有效,當然這是主要的。 但我真的不喜歡將數組索引計算為find調用的副作用。 然而,再次計算它似乎有點過分了。 我也不太喜歡idInObjLens這個名字,而且我總是覺得如果我沒有一個好名字,我就會錯過一些基本的東西。 (我對myLens沒有同樣的反對意見,因為我認為你會為你的用例有一個更好的名字。)

這與 Hitmand 的解決方案之間的最大區別在於,該鏡頭不需要您預先知道外部 object 中的哪個鍵持有您的 ID 項目。 這給解決方案增加了相當多的復雜性,但使其 API 更加靈活。

您 map 屬性內的所有數組,並使用R.when進化所有具有匹配id的對象,並替換屬性的(在您的情況下title )值:

 const { curry, map, when, propEq, evolve, always } = R const fn = curry((id, prop, content) => map(map( // map all objects of all properties when( propEq('id', id), // if the id of an object matches evolve({ [prop]: always(content) })) // evolve it's property to the content ) )) const data = {"31":[{"id":"11","title":"ramda heeeelp"},{"id":"12","title":"ramda 123"}],"33":[{"id":"3","title":"..."}],"4321":[{"id":"1","title":"hello world"}]} const result = fn('12', 'title', 'new heading 123')(data) console.log(result);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>

暫無
暫無

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

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