is there a function in lodash to replace matched item

前端 未结 15 2293
孤街浪徒
孤街浪徒 2020-12-07 13:42

I wonder if there is a simpler method in lodash to replace an item in a JavaScript collection? (Possible duplicate but I did not understand the answer there:)

I look

15条回答
  •  情歌与酒
    2020-12-07 14:07

    As the time passes you should embrace a more functional approach in which you should avoid data mutations and write small, single responsibility functions. With the ECMAScript 6 standard, you can enjoy functional programming paradigm in JavaScript with the provided map, filter and reduce methods. You don't need another lodash, underscore or what else to do most basic things.

    Down below I have included some proposed solutions to this problem in order to show how this problem can be solved using different language features:

    Using ES6 map:

    const replace = predicate => replacement => element =>
      predicate(element) ? replacement : element
     
    const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
    const predicate = element => element.id === 1
    const replacement = { id: 100, name: 'New object.' }
    
    const result = arr.map(replace (predicate) (replacement))
    console.log(result)


    Recursive version - equivalent of mapping:

    Requires destructuring and array spread.

    const replace = predicate => replacement =>
    {
      const traverse = ([head, ...tail]) =>
        head
        ? [predicate(head) ? replacement : head, ...tail]
        : []
      return traverse
    }
     
    const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
    const predicate = element => element.id === 1
    const replacement = { id: 100, name: 'New object.' }
    
    const result = replace (predicate) (replacement) (arr)
    console.log(result)


    When the final array's order is not important you can use an object as a HashMap data structure. Very handy if you already have keyed collection as an object - otherwise you have to change your representation first.

    Requires object rest spread, computed property names and Object.entries.

    const replace = key => ({id, ...values}) => hashMap =>
    ({
      ...hashMap,       //original HashMap
      [key]: undefined, //delete the replaced value
      [id]: values      //assign replacement
    })
    
    // HashMap <-> array conversion
    const toHashMapById = array =>
      array.reduce(
        (acc, { id, ...values }) => 
        ({ ...acc, [id]: values })
      , {})
      
    const toArrayById = hashMap =>
      Object.entries(hashMap)
      .filter( // filter out undefined values
        ([_, value]) => value 
      ) 
      .map(
        ([id, values]) => ({ id, ...values })
      )
    
    const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
    const replaceKey = 1
    const replacement = { id: 100, name: 'New object.' }
    
    // Create a HashMap from the array, treating id properties as keys
    const hashMap = toHashMapById(arr)
    console.log(hashMap)
    
    // Result of replacement - notice an undefined value for replaced key
    const resultHashMap = replace (replaceKey) (replacement) (hashMap)
    console.log(resultHashMap)
    
    // Final result of conversion from the HashMap to an array
    const result = toArrayById (resultHashMap)
    console.log(result)

提交回复
热议问题