用lodash在deep path创建一个空对象



我需要在深度路径上创建一个空对象,但只有在它不存在的情况下,并返回对该对象的引用。

这可以通过使用_.has, _.set_.get来实现

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

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

我想知道是否有一种方法可以做到这一点,而不需要额外的函数/库。


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

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

  • v4.0.0 _。differenceBy(array, [values], [iteratee= _identity])
  • v3.0.0 _。dropRightWhile(数组,[谓词= _.identity])
  • v3.0.0 _。dropWhile(数组,[谓词= _.identity])
  • v1.1.0 _。findIndex(数组,[谓词= _。身份],[fromIndex = 0])
  • v2.0.0 _。findLastIndex(数组,[谓词= _。身份],[fromIndex = array.length-1])
  • v4.0.0 _.intersectionBy((数组),[iteratee = _.identity])
  • v4.0.0 _。sortedIndexBy(array, value, [iteratee= _identity])
  • v4.0.0 _。sortedLastIndexBy(array, value, [iteratee= _identity])
  • v3.0.0 _。takeRightWhile(数组,[谓词= _.identity])
  • v3.0.0 _。takeWhile(数组,[谓词= _.identity])
  • v4.0.0 _。unionBy((数组),[iteratee = _.identity])
  • v4.0.0 _。uniqBy(数组,[iteratee = _.identity])
  • v4.0.0 _。xorBy((数组),[iteratee = _.identity])
  • v4.1.0 _。zipObjectDeep([道具=[]],[值= []])

  • v0.5.0 _。countBy(收集、[iteratee = _.identity])
  • v0.1.0 _。每个(收集、[谓词= _.identity])
  • v0.1.0 _。过滤器(收集、[谓词= _.identity])
  • v0.1.0 _。找到(收集、[谓词= _.identity])
  • v0.1.0 _。groupBy(收集、[iteratee = _.identity])
  • v4.0.0 _。invokeMap(collection, path, [args])
  • v0.1.0 _。地图(收集、[iteratee = _.identity])
  • v3.0.0 _。分区(收集、[谓词= _.identity])
  • v0.1.0 _。拒绝(收集、[iteratee = _.identity])
  • v0.1.0 _。一些(收集、[iteratee = _.identity])
数学

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

  • v1.0.0 _。(对象,(路径))
  • v1.1.0 _。[谓词= _.identity] findKey(对象)
  • v2.0.0 _。[谓词= _.identity] findLastKey(对象)
  • v3.7.0 _。get(object, path, [defaultValue])
  • v0.1.0 _。(对象,路径)
  • v4.0.0 _。之内(对象,路径)
  • v4.0.0 _。调用(object, path, [args])
  • v2.4.0 _。[iteratee = _.identity] mapValues(对象)
  • v0.1.0 _。(路径)省略(对象)
  • v0.1.0 _。选择(对象,路径)
  • v0.1.0 _。result(object, path, [defaultValue])
  • v3.7.0 _。set(object, path, value)
  • v4.0.0 _。setWith(object, path, value, [customizer])
  • v4.0.0 _。设置(对象,路径)
  • v4.6.0 _。update(object, path, updater)
  • v4.6.0 _。updateWith(object, path, updater, [customizer])

Util

  • v4.0.0 _.iteratee ([func = _.identity])
  • v3.2.0 _。matchesProperty(路径,srcValue)
  • v3.7.0 _。方法(路径,(args))
  • v3.7.0 _。(args)方法(对象)
  • v2.4.0 _.property(路径)
  • v3.0.0 _.propertyOf(对象)
  • v4.0.0 _.toPath(值)

>

链式方法,即在序列序列中调用的方法,例如:

_(value).chained().method().value();
  • v1.0.0 _.prototype.at((路径))

您可以这样避免_.has:

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

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

在额外的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;

使用新的可选链操作符和逻辑空赋值,在这种特殊情况下就不需要使用lodash了(如果可以接受用默认值填充/定义some.deep.path),例如:

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

遗憾的是,可选的链接赋值还不可用。见https://stackoverflow.com/a/58882121/1949503

只有一个缺点,那就是需要重复使用属性访问器(some.deep.path)来检索值。但是在这个例子中,我们将使用Typescript/JSDoc实现自动补全,而不像lodash函数的path参数(字符串或数组)

如果只需要获取路径上的值,那么普通的try/catch就足够了:

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

现在可以使用_.setWith

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

返回
{some:{deep:{path:4}}

你可以用

直接进入一行中的点
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' }}}}

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

如果路径不存在,则创建该路径,否则不修改。仍然不确定如何避免get ..

最新更新