【问题标题】:Underscore equivalent of Lodash _.get and _.has下划线等效于 Lodash _.get 和 _.has
【发布时间】:2017-02-04 15:43:37
【问题描述】:

我正在尝试搜索 Lodash _.get_.has 的 Underscore 等效项,它能够直接访问嵌套对象值的存在和值,而无需检查其父对象的存在。

但是,在我看来,下划线_.get_.has 只能检查第一级的值。

var object = { 'a': { 'b': 2 } };
_.has(object, 'a.b'); // lodash shows true
_.has(object, 'a.b'); // underscore shows false

【问题讨论】:

    标签: javascript underscore.js lodash


    【解决方案1】:

    据我所知,undercore 不会执行深度搜索,因此您必须满足于浅层 hasget(或更改为 lodash)。

    您也可以尝试自己实现它(您可以检查 lodash 的实现并尝试复制它或提出自己的解决方案)。

    这是has 问题的简单解决方案(get 将类似),使用递归和当前下划线has 的实现。

    希望对你有帮助。

    var a = {
      a: 1,
      b: {
        a: { c: { d: 1 }}
      }
    };
    
    var hasDeep = function(obj, path) {
      if(!path) return true;
      
      var paths = path.split('.'),
        nPath = _.first(paths);
      return _.has(obj, nPath) && hasDeep(obj[nPath], _.rest(paths).join('.'));
    }
    
    console.log(hasDeep(a, 'b.a.c.d'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>

    【讨论】:

      【解决方案2】:

      您可以通过 _.mixin 使用自定义方法为下划线添加扩展名

      这是一个像 _.getlodash 一样工作的 mixin,传递对象的链来评估,即

      用法

      _.get(a, 'a[0].b');

      "collectionValue1" // you will get

      混音

      _.mixin({
          get: function(obj, path) {
              if (!obj && !path) {
                  return undefined;
              } else {
                  var paths;
      
                  if (!_.isEmpty(path.match(/^\[\d\]/))) {
                      paths = path.replace(/^[\[\]]/g, '').split(/\./);
                      nPath = _.first(paths[0].replace(/\]/, ''));
                  } else {
                      paths = path.split(/[\.\[]/);
                      nPath = _.first(paths);
                  }
      
                  remainingPath = _.reduce(_.rest(paths), function(result, item) {
                      if (!_.isEmpty(item)) {
                          if (item.match(/^\d\]/)) {
                              item = "[" + item;
                      }
                          result.push(item);
                      }
      
                      return result;
                  }, []).join('.');
      
                  if (_.isEmpty(remainingPath)) {
                      return obj[nPath];
                  } else {
                      return _.has(obj, nPath) && _.get(obj[nPath], remainingPath);
                  }
              }
          }
      });
      

      查看示例

      var a = {
      a: [
        { b: "collectionValue1" },
        { b: "collectionValue2", list: [ { item: "listValue1" }, { item: [{value: "Working"}] }] }
        ],
        b: {
          a: {
            c: {
              d:"success"
            }
          }
        }
      };
      
      _.mixin({
        get: function(obj, path) {
            if (!obj && !path) {
                return undefined;
            } else {
                var paths;
      
                if (!_.isEmpty(path.match(/^\[\d\]/))) {
                    paths = path.replace(/^[\[\]]/g, '').split(/\./);
                    nPath = _.first(paths[0].replace(/\]/, ''));
                } else {
                    paths = path.split(/[\.\[]/);
                    nPath = _.first(paths);
                }
      
                remainingPath = _.reduce(_.rest(paths), function(result, item) {
                    if (!_.isEmpty(item)) {
                        if (item.match(/^\d\]/)) {
                            item = "[" + item;
                    }
                        result.push(item);
                    }
      
                    return result;
                }, []).join('.');
      
                if (_.isEmpty(remainingPath)) {
                    return obj[nPath];
                } else {
                    return _.has(obj, nPath) && _.get(obj[nPath], remainingPath);
                }
            }
          }
        });
      
        console.log(_.get(a, 'a[0].b'));
        console.log(_.get(a, 'b.a.c.d'));
        console.log(_.get(a, 'a[1].b'));
        console.log(_.get(a, 'a[1].list[0].item'));
        console.log(_.get(a, 'a[1].list[1].item[0].value'));
      <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

      【讨论】:

      • 这为我在一个使用下划线的项目中节省了大量时间(和挫败感),来自 lodash。但是,逻辑确实需要更改以匹配 lodash 的输出:特别是,当缺少属性时,来自 lodash 的 _.get 返回 undefined - 这将返回 false 更改为 codepen.io/fluffynuts/pen/RJgjLo 修复了这个问题(我也在那里添加了 lodash 的 lowerCase - 如果你喜欢,请忽略它)
      【解决方案3】:

      有一些外部库提供此功能:

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-13
      相关资源
      最近更新 更多