相当于 Lodash _.get 和 _.has 的下划线

Underscore equivalent of Lodash _.get and _.has

我正在尝试搜索 Lodash _.get_.has 的 Underscore 等效项,它可以直接访问嵌套 object 值的存在和值而不需要检查其 parents.

是否存在

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

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

据我所知,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>

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

您可以通过 _.mixin

使用自定义方法添加下划线扩展

这是一个 mixin,其工作方式类似于 lodash_.get 传递对象链以进行评估,即

用法

_.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>