Javascript 这种动态合并两个对象的解决方案是否更简单?

Javascript 这种动态合并两个对象的解决方案是否更简单?,javascript,ecmascript-6,javascript-objects,Javascript,Ecmascript 6,Javascript Objects,如果我有这个root对象: const root={ 名单:{ 第一:错, 第二:错, 第三:错, 第四:错误 } }; 并希望创建一个具有相同结构但更改单个变量的新对象。我可以用以下方法来做: const结果={ …根, 名单:{ …root.list, 第一:对 } } 因此,结果将是: { “名单”:{ “第一”:对, “第二”:假, "三":假,, “forth”:假 } } 一切都正常,但我需要以动态的方式做同样的事情。假设我传递根对象,即需要更新的属性的完整路径。首先,作为字符

如果我有这个
root
对象:

const root={
名单:{
第一:错,
第二:错,
第三:错,
第四:错误
}
};
并希望创建一个具有相同结构但更改单个变量的新对象。我可以用以下方法来做:

const结果={
…根,
名单:{
…root.list,
第一:对
}
}
因此,结果将是:

{
“名单”:{
“第一”:对,
“第二”:假,
"三":假,,
“forth”:假
}
}
一切都正常,但我需要以动态的方式做同样的事情。假设我传递
根对象,即需要更新的
属性的完整路径。首先,
作为字符串和值传递。我找到了一个解决方案:

const merge=require('lodash')。merge;
常数根={
名单:{
第一:错,
第二:错,
第三:错,
第四:错误
}
};
函数createObjectByPathAndValue(路径,值){
常量键=(路径| |“”)。拆分('.')| |[];
函数createObjectByPathAndValue(根、键、值){
如果(keys.length==1){
根[键[0]]=值;
}否则{
常数键=键。拼接(0,1);
root[key]=createObjectByPathAndValue({},key,value);
}
返回根;
}
const result=createObjectByPathAndValue({},键,值);
返回结果;
}
const changes=createObjectByPathAndValue('list.first',true);
const result=merge({},root,changes);
log(JSON.stringify(result,null,2));
但是,让我们承认它很麻烦,而且代码太多。我认为我没有使用现代javascript的所有可能性,而且可以做得更简单。我说得对吗


注意:必须创建新对象,即不允许对现有对象进行变异(我需要它来更新React的状态)

您可以深度克隆对象并更改值:

const {cloneDeep, toPath, set} = require('lodash');

const root = {
    list: {
        first: false,
        second: false,
        third: false,
        forth: false
    }
};

const result = cloneDeep(root);
set(result, toPath('list.first'), true);

console.log(JSON.stringify(result, null, 2));
下面是一个示例(JSFIDLE不支持
require
):

const root={
名单:{
第一:错,
第二:错,
第三:错,
第四:错误
}
};
const result=\克隆深度(根);
_.set(结果,u.toPath('list.first'),true);
log(JSON.stringify(result,null,2))

您可以深度克隆对象并更改值:

const {cloneDeep, toPath, set} = require('lodash');

const root = {
    list: {
        first: false,
        second: false,
        third: false,
        forth: false
    }
};

const result = cloneDeep(root);
set(result, toPath('list.first'), true);

console.log(JSON.stringify(result, null, 2));
下面是一个示例(JSFIDLE不支持
require
):

const root={
名单:{
第一:错,
第二:错,
第三:错,
第四:错误
}
};
const result=\克隆深度(根);
_.set(结果,u.toPath('list.first'),true);
log(JSON.stringify(result,null,2))

我使用
lodash/fn/set
软件包中的
set
功能结束,如中所述

const setFp=require('lodash/fp/set');
常数根={
名单:{
第一:错,
第二:错,
第三:错,
第四:错误
}
};
const newRoot=setFp(`list.first`,true,root)//将创建一个新对象

阅读有关软件包的更多信息。

我使用
lodash/fn/set
软件包中的
set
函数结束了此过程,如中所述

const setFp=require('lodash/fp/set');
常数根={
名单:{
第一:错,
第二:错,
第三:错,
第四:错误
}
};
const newRoot=setFp(`list.first`,true,root)//将创建一个新对象

阅读更多关于包装的信息。

您的实际问题是什么?合并两个对象还是创建一个对象?合并部分是两行。或者你真正的问题是如何深度克隆一个对象并更改一个值?实际上,我需要创建一个新对象,该对象的修改属性由path to property
path.to.property
和value指定。标题有误导性。这不是合并两个对象。这是将(deep)属性设置为值。洛达斯
set
。你的实际问题是什么?合并两个对象还是创建一个对象?合并部分是两行。或者你真正的问题是如何深度克隆一个对象并更改一个值?实际上,我需要创建一个新对象,该对象的修改属性由path to property
path.to.property
和value指定。标题有误导性。这不是合并两个对象。这是将(deep)属性设置为值。Lodash
set
。好的,现在告诉我如何从
“result.list.first”
result.list.first
,注意第一个是字符串,而第二个是对象。我更新了我的答案,因为它可能不清楚,我已经按字符串给出了
“path.to.property”
,我需要将其转换为实际对象。@Anatoly我修复了它。@Anatoly Lodash有一个
set
functionBtw,Lodash有一个
set
的fp版本,它创建了一个新对象:好的,现在告诉我你是如何从
“result.list.first”
result.list.first
,注意第一个是字符串,第二个是对象。我更新了我的答案,因为它可能不清楚,我用字符串给出了
“path.to.property”
,我需要将其转换为实际对象。@Anatoly我修复了它。@Anatoly Lodash有一个
函数BTW,Lodash有一个
的fp版本,它创建了一个新对象: