admin管理员组文章数量:1356908
I am looking to set inner properties of an object only if they already exist. Lodash _.set
will create the whole hierarchy if it does not exist.
Is there an easy way to do this ? (Without and if statement ?)
Snippet below:
const obj = {a: {b: 1}};
_.set(obj, 'a.b', 2);
console.log(obj); // Great !
_.set(obj, 'a.c', 1);
console.log(obj); // Great but not what I want. I would like c not to be set because it does not exist in the first place
<script src=".js/4.17.4/lodash.min.js"></script>
I am looking to set inner properties of an object only if they already exist. Lodash _.set
will create the whole hierarchy if it does not exist.
Is there an easy way to do this ? (Without and if statement ?)
Snippet below:
const obj = {a: {b: 1}};
_.set(obj, 'a.b', 2);
console.log(obj); // Great !
_.set(obj, 'a.c', 1);
console.log(obj); // Great but not what I want. I would like c not to be set because it does not exist in the first place
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Share
Improve this question
asked Dec 7, 2017 at 2:53
klugjoklugjo
20.9k10 gold badges64 silver badges81 bronze badges
2
-
6
Check it with
_.has
first? – zerkms Commented Dec 7, 2017 at 2:57 - 1 lodash./docs/4.17.4#has – charlietfl Commented Dec 7, 2017 at 2:58
4 Answers
Reset to default 3you can try by this way
const obj = {a: {b: 1}};
_.set(obj, 'a.b', 2);
console.log(obj); // Great !
_.has(obj,'a.c')==true?_.set(obj, 'a.c', 1):""
console.log(obj); // Great but not what I want. I would like c not to be set because it does not exist in the first place
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
The answer from Kalaiselvan A below put me on the way but this is not quite what I was looking for.
Using the same idea but improving the ternary gives me the following solution which I am happy with.
const obj = {a: {b: 1}};
_.has(obj, 'a.b') && _.set(obj, 'a.b', 2);
console.log(obj);
_.has(obj, 'a.c') && _.set(obj, 'a.c', 2);
console.log(obj);
<script src="https://cdn.jsdelivr/lodash/4/lodash.min.js"></script>
You could look at Object.seal
Though, you'll want to "deeply" seal the object:
const sealDeep = obj => {
const sealProps = o => {
Object.values(o).forEach(value => {
if (typeof value === 'object') {
sealProps(value);
Object.seal(value);
}
});
};
sealProps(obj);
Object.seal(obj);
};
var x = {
hello: {
world: {
foo: 1,
bar: 2
},
bat: '3'
},
foo2: 4
};
sealDeep(x);
console.log(JSON.stringify(x));
x.newthing = 999;
x.hello.newthing = 999;
x.hello.world.newthing = 999;
x.hello.world.foo = 999;
console.log(JSON.stringify(x));
I was looking for the same thing, and settled for this non-lodash solution
function overridePropertyByJsonPath(obj, thePath, value) {
const path = thePath.split('.');
let i
for (i = 0; i < path.length - 1; i++) {
const val = obj[path[i]]
if (val === undefined) {
return
}
obj = val
}
if (obj[path[i]] === undefined) {
return
}
obj[path[i]] = value;
}
It passes all these tests I came up with
describe("Key overriding should allow ", () => {
it("override shallow key", () => {
const o = { a1: true }
overridePropertyByJsonPath(o, "a1", false)
expect(o["a1"]).toEqual(false)
})
it("no extra key with non-empty object", () => {
const o = { a1: true }
overridePropertyByJsonPath(o, "a2", false)
expect(o["a2"]).toBeUndefined()
})
it("no extra keys with empty object", () => {
const o = {}
overridePropertyByJsonPath(o, "not_there_to_begin_with", true)
expect(o["not_there_to_begin_with"]).toBeUndefined()
})
it("no extra keys in override (deep)", () => {
const o = { a: { b: true } }
overridePropertyByJsonPath(o, "a.b.not_there_to_begin_with", true)
expect(o["a"]["b"]["not_there_to_begin_with"]).toBeUndefined()
})
it("no extra keys in override (too deep)", () => {
const o = { a: { b: true } }
overridePropertyByJsonPath(o, "a.b.c.not_there_to_begin_with", true)
expect(o["a"]["b"]["c"]).toBeUndefined()
})
it("override deep key", () => {
const o = { a: { b: true } }
overridePropertyByJsonPath(o, "a.b", false)
expect(o["a"]["b"]).toEqual(false)
})
it("override deep key with array value", () => {
const o = { a: { b: [1] } }
overridePropertyByJsonPath(o, "a.b", [2])
expect(o["a"]["b"]).toContain(2)
expect(o["a"]["b"].length).toEqual(1)
})
it("override deep key with object value", () => {
const o = { a: { b: {} } }
overridePropertyByJsonPath(o, "a.b", { "x": true })
expect(o["a"]["b"]["x"]).toEqual(true)
})
})
本文标签: javascriptLodash set only if object existsStack Overflow
版权声明:本文标题:javascript - Lodash _.set only if object exists - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744063844a2584621.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论