JS - deep map function

后端 未结 8 527
挽巷
挽巷 2020-12-06 04:48

Underscore.js has a very useful map function.

_.map([1, 2, 3], function(num){ return num * 3; });
=> [3, 6, 9]
_.map({one: 1, two: 2, three: 3         


        
8条回答
  •  Happy的楠姐
    2020-12-06 05:38

    I've published a package called Deep Map to address this very need. And in case you want to map an object's keys rather than its values, I've written Deep Map Keys.

    Notably, none of the answers on here address a significant problem: circular references. Here is a somewhat naive implementation that deals with these rotters:

    function deepMap(value, mapFn, thisArg, key, cache=new Map()) {
      // Use cached value, if present:
      if (cache.has(value)) {
        return cache.get(value);
      }
    
      // If value is an array:
      if (Array.isArray(value)) {
        let result = [];
        cache.set(value, result); // Cache to avoid circular references
    
        for (let i = 0; i < value.length; i++) {
          result.push(deepMap(value[i], mapFn, thisArg, i, cache));
        }
        return result;
    
      // If value is a non-array object:
      } else if (value != null && /object|function/.test(typeof value)) {
        let result = {};
        cache.set(value, result); // Cache to avoid circular references
    
        for (let key of Object.keys(value)) {
          result[key] = deepMap(value[key], mapFn, thisArg, key, cache);
        }
        return result;
    
      // If value is a primitive:
      } else {
        return mapFn.call(thisArg, value, key);
      }
    }
    

    And you can use it like this:

    class Circlular {
      constructor() {
        this.one = 'one';
        this.arr = ['two', 'three'];
        this.self = this;
      }
    }
    
    let mapped = deepMap(new Circlular(), str => str.toUpperCase());
    
    console.log(mapped.self.self.self.arr[1]); // 'THREE'
    

    Of course, the example above is in ES2015. See Deep Map for a more optimized – though less terse – ES5-compatible implementation written in TypeScript.

提交回复
热议问题