使用 lodash 或任何其他库深度更新 ES6 中的对象的更好方法

Guy*_*Guy 5 javascript ecmascript-6 lodash

寻找一种深度更新/合并测试的方法:

目前,我们正在这样做:

 {
    ..._companies,
    ['c124']: {
        ..._companies.c124,
        ['fields']: {
            ..._companies.c124.fields,
            ['f4']: {
                ..._companies.c124.fields.f4,
                value: 'white'
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

理想情况下我们会这样做:

update_merge(_companies, {
    c124: {
        fields: {
            f4: {
                value:'white'
            }
        }
    }
})
Run Code Online (Sandbox Code Playgroud)

简单的深度合并在这种情况下不起作用,因为它完全取代了c124密钥。

原始 _companies 片段:

const companies = {
    c123: {
        id: 123,
        name: 'Company one',
        fields: {...} // fields                   
    },
    c124: {
        id: 124,
        name: 'Company two',
        fields: {
            f1: {...}, //...fields                   
            f2: {...}, //...fields                   
            f3: {...}, //...fields                   
            f4: {
                id: 4,
                fieldType: "shortText",longText
                title: "favorite color",
                value: 'green', // <==== only this will change
            },
        },
    }
}
Run Code Online (Sandbox Code Playgroud)

这个预期结果:

const companies = {
    c123: {
        id: 123,
        name: 'Company one',
        fields: {...} // fields                   
    },
    c124: {
        id: 124,
        name: 'Company two',
        fields: {
            f1: {...}, //...fields                   
            f2: {...}, //...fields                   
            f3: {...}, //...fields                   
            f4: {
                id: 4,
                fieldType: "shortText",longText
                title: "favorite color",
                value: 'white', // <==== this changed
            },
        },
    }
}
Run Code Online (Sandbox Code Playgroud)

Ori*_*ori 5

Lodash_.merge()是递归的,允许您更新嵌套键

注意:我将值从蓝色更改为红色

const companies = {"c123":{"id":123,"name":"Company one","fields":{}},"c124":{"id":124,"name":"Company two","fields":{"f1":{},"f2":{},"f3":{},"f4":{"id":4,"fieldType":"shortText","title":"favorite color","value":"blue"}}}};

const newCompanies = _.merge({}, companies, {
    c124: {
        fields: {
            f4: {
                value:'red'
            }
        }
    }
})

console.log(newCompanies);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

_.set()如果您可以改变对象,另一种选择是使用 lodash :

const companies = {"c123":{"id":123,"name":"Company one","fields":{}},"c124":{"id":124,"name":"Company two","fields":{"f1":{},"f2":{},"f3":{},"f4":{"id":4,"fieldType":"shortText","title":"favorite color","value":"blue"}}}};

_.set(companies, ['c124', 'fields', 'f4', 'value'], 'red')

console.log(companies);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

但是,如果您经常这样做,并且需要一个不可变的对象(例如在 redux 中),我建议对树进行规范化,使其具有更浅、更容易访问的叶子。