【问题标题】:Create an empty object at deep path with lodash使用 lodash 在深度路径创建一个空对象
【发布时间】:2015-11-30 13:41:07
【问题描述】:

我需要在深层路径上创建一个空对象,但前提是它不存在并返回对该对象的引用。

这可以通过使用_.has_.set 然后_.get 来完成

let path = 'some.deep.path';

if (!_.has(object, path)) {
    _.set(object, path, {});
}

let descendant = _.get(object, path);

我想要的是避免重复objectpath(或引入path 变量以避免重复path 值)

我想知道是否有办法在没有额外功能/库的情况下做到这一点。


接受或处理路径的 lodash 方法列表。按字母顺序

这包括处理数组/集合并接受_.property iteratee/predicate 简写的方法,即当一个字符串作为参数提供时,它被传递给_.property 方法,该方法创建一个函数,该函数返回给定对象路径的值(由主函数给出,例如_.map)。

数组

收藏

  • v0.5.0 _.countBy(collection, [iteratee=_.identity])
  • v0.1.0 _.every(collection, [predicate=_.identity])
  • v0.1.0 _.filter(collection, [predicate=_.identity])
  • v0.1.0 _.find(collection, [predicate=_.identity])
  • v0.1.0 _.groupBy(collection, [iteratee=_.identity])
  • v4.0.0 _.invokeMap(collection, path, [args])
  • v0.1.0 _.map(collection, [iteratee=_.identity])
  • v3.0.0 _.partition(collection, [predicate=_.identity])
  • v0.1.0 _.reject(collection, [iteratee=_.identity])
  • v0.1.0 _.some(collection, [iteratee=_.identity])

数学

  • v4.0.0 _.maxBy(array, [iteratee=_.identity])
  • v4.7.0 _.meanBy(array, [iteratee=_.identity])
  • v4.0.0 _.minBy(array, [iteratee=_.identity])
  • v4.0.0 _.sumBy(array, [iteratee=_.identity])

对象

  • v1.0.0 _.at(object, [paths])
  • v1.1.0 _.findKey(object, [predicate=_.identity])
  • v2.0.0 _.findLastKey(object, [predicate=_.identity])
  • v3.7.0 _.get(object, path, [defaultValue])
  • v0.1.0 _.has(对象,路径)
  • v4.0.0 _.hasIn(对象,路径)
  • v4.0.0 _.invoke(object, path, [args])
  • v2.4.0 _.mapValues(object, [iteratee=_.identity])
  • v0.1.0 _.omit(object, [paths])
  • v0.1.0 _.pick(object, [paths])
  • v0.1.0 _.result(object, path, [defaultValue])
  • v3.7.0 _.set(对象、路径、值)
  • v4.0.0 _.setWith(object, path, value, [customizer])
  • v4.0.0 _.unset(对象,路径)
  • v4.6.0 _.update(对象、路径、更新程序)
  • v4.6.0 _.updateWith(object, path, updater, [customizer])

实用程序

序列

链式方法,即在seq关系中调用的方法,例如:

_(value).chained().method().value();

【问题讨论】:

    标签: javascript lodash


    【解决方案1】:

    在额外的lodash-deep 库中有一个_.deepDefault 方法,用于检查propertyPath 的值是否解析为undefined,如果是这种情况,则将其设置为defaultValue

    var descendant = _.deepDefault(object, 'some.deep.path', {});
    

    该库不再更新,因为 Lodash 现在原生支持大部分功能,所以这里有一个 lodash mixin 函数的实现:

    function getOrSetDefault(object, path, defaultValue) {
        const descendant = _.get(object, path);
        if (descendant === undefined) {
            _.set(object, path, defaultValue);
        }
        return descendant;
    }
    
    _.mixin({ getOrSetDefault });
    
    const a = _.getOrSetDefault(object, 'some.deep.path', 42);
    const b = _.getOrSetDefault(object, 'some.other.deep.path', {});
    b.c = 42;
    

    使用新的可选链接运算符和逻辑空值分配,对于这种特殊情况(如果可以使用默认值填充/定义 some.deep.path),则无需使用 lodash,例如:

    some?.deep?.path ??= {}
    const { foo } = some.deep.path
    

    不幸的是,可选的链接分配尚不可用。 见https://stackoverflow.com/a/58882121/1949503

    只有一个缺点是需要重复属性访问器 (some.deep.path) 来检索值。但是在这种情况下,我们将使用 Typescript/JSDoc 进行自动补全,这与 lodash 函数的路径参数(字符串或数组)不同

    如果只需要在路径中获取价值,那么原版 try/catch 就足够了:

    let foo: Foo;
    try {
      foo = some.deep.path.foo
    } catch {}
    

    【讨论】:

      【解决方案2】:

      你可以在一行中直奔主题

      const object = _.set({}, 'some.deep.path', {value: 'foo'})
      

      或者,如果您已经有一个要更新的对象

      const obj = {some: {deep: {path: {barbecue: '?'}}}}
      const path = 'some.deep.path'
      
      _.set(obj, path, {..._.get(obj, path, {}), foo: 'bar'})
      // => {some: {deep: {path: {barbecue: '?', foo: 'bar' }}}}
      

      【讨论】:

      • 这将覆盖整个some.deep.path 对象,而不是添加/更改value(假设some.deep.path 已经包含{ value: 'bar', otherValue: 'egg' }
      • _.set(obj, path, _.get(obj, path, {})); 是一个很好的方法 ? 即使它需要引用 objpath 两次。任务是获取对 path 处对象的引用,如果该对象不存在,则在 path 处创建该对象。 _.set 返回 obj 而不是 obj.some.deep.path.barbecue ;)
      【解决方案3】:

      现在你可以使用 _.setWith

      setWith({}, "some.deep.path", value, Object);
      

      返回

      {some:{deep:{path:4}}
      

      【讨论】:

        【解决方案4】:

        这个怎么样:

        function getDefault(obj, path, defaultValue) {
          _.update(obj, path, d => d ? d : {})
          return _.get(obj, path);
        }
        

        如果路径不存在,则创建该路径,否则不更改。 仍然不确定避免get 的方法..

        【讨论】:

          【解决方案5】:

          您可以通过以下方式避免_.has

          var path = 'some.deep.path',
          descendant = _.get(object, path);
          if (!descendant) {
              descendant = {};
              _.set(object, path, descendant);
          }
          

          因此只遍历路径 2 次,而不是 3 次。

          【讨论】:

          • 如果路径包含数字键则不起作用:var path = 'some.22.11'
          猜你喜欢
          • 2021-08-31
          • 2021-10-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-08
          • 2016-05-05
          相关资源
          最近更新 更多