简体   繁体   English

如何创建一个新的 Object 而不是对其进行变异 - javascript?

[英]How to create a new Object instead of mutating it - javascript?

Here i am having a Object ie ApiData1 .在这里,我有一个 Object 即ApiData1 Where it has color key value pair inside properties .它在properties中有color键值对。 I am changing the color values according to ApiData2 value numberOfProjects , and having a range where numberOfProjects values lies between a set of range i am updating the color value.我正在根据ApiData2numberOfProjects更改颜色值,并且具有numberOfProjects值位于一组范围之间的范围,我正在更新color值。 It is working fine.它工作正常。 But after updating, I am setting this value in a state [React].但是更新后,我在 state [React] 中设置了这个值。 However on initial load color has updated and working fine.但是,在初始加载时,颜色已更新并且工作正常。 After a button click i am doing exactly this process with Different ApiData2 value.单击按钮后,我正在使用不同的 ApiData2 值执行此过程。 ApiData1 color value gets updated. ApiData1 color值得到更新。 But react doesn't detect the change.但反应没有检测到变化。

I suspect because of mutating the ApiData1 .我怀疑是因为ApiData1发生了变异。 Its not picking the prop change.Instead of mutating is there any way to create a new ApiData1 value with it.它没有选择道具更改。有什么方法可以用它创建一个新的ApiData1值,而不是改变。 Anyway to recreate this logic.无论如何要重新创建这个逻辑。

Your help or suggestion is much appreciated.非常感谢您的帮助或建议。

Thanks in advance.提前致谢。

Here is the WORKING DEMO LINK这是工作演示链接


let ApiData1 = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "MultiPolygon"
            },
            "properties": {
                "color": 1,
                "id": 10,
                "stateId": 10,
                "name": "Tamil Nadu",
                "code": "TN"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "MultiPolygon"
            },
            "properties": {
                "color": 1,
                "id": 11,
                "stateId": 11,
                "name": "Karnataka",
                "code": "KA"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "MultiPolygon"
            },
            "properties": {
                "color": 1,
                "id": 12,
                "stateId": 12,
                "name": "Pondicherry",
                "code": "PY"
            }
        }
    ]
}

let ApiData2 = [
    {
        id: 10,
        name: "Tamil Nadu",
        code: "TN",
        latitude: 29.9964948,
        longitude: 81.6855882,
        latestMetric: {
            stateId: 10,
            year: 0,
            numberOfProjects: 1433,
        }
    },
    {
        id: 11,
        name: "Karnataka",
        code: "KA",
        latitude: 21.9964948,
        longitude: 82.6855882,
        latestMetric: {
            stateId: 11,
            year: 0,
            numberOfProjects: 3500,
        }
    },
    {
        id: 12,
        name: "Pondicherry",
        code: "PY",
        latitude: 22.9964948,
        longitude: 87.6855882,
        latestMetric: {
            stateId: 12,
            year: 0,
            numberOfProjects: 5500,
        }
    }
];

function updateColor() {
    function updateColorValue(colorJsonObject, colorValue) {
        let updatedProperties = {
            ...colorJsonObject.properties,
            color: colorValue
        };
        colorJsonObject.properties = updatedProperties;
        return { ...colorJsonObject };
    }

    let range = [
        {
            "Minimum": 1,
            "Maximum": 2000,
            "color": 1
        },
        {
            "Minimum": 2000,
            "Maximum": 4000,
            "color": 2
        },
        {
            "Minimum": 4000,
            "Maximum": 6000,
            "color": 3
        }
    ]

    ApiData1.features.map(colorObject =>
        ApiData2.map(apiData => {
            if (
                colorObject.properties.stateId === apiData.latestMetric.stateId
            ) {
                range.map(i => {
                    if (
                        apiData.latestMetric.numberOfProjects >= i.Minimum &&
                        apiData.latestMetric.numberOfProjects <= i.Maximum
                    ) {
                        updateColorValue(colorObject, i.color);
                    }
                });
            }
        })
    );
    return ApiData1;
}

let colorValue = updateColor();

console.log(colorValue);

I have done something like this to create a newObject, instead of mutating it,我做了这样的事情来创建一个新对象,而不是改变它,

  
     function updateProperties(colorJsonObject, colorValue) {
        let updatedProperties = {
            ...colorJsonObject.properties,
            color: colorValue
        };
        console.log(updatedProperties)
        return updatedProperties;
        
    }
    let newData = {...ApiData1}

    newData.features.map(colorObject =>
        ApiData2.map(apiData => {
            if (
                colorObject.properties.stateId === apiData.latestMetric.stateId
            ) {
                range.map(i => {
                    if (
                        apiData.latestMetric.numberOfProjects >= i.Minimum &&
                        apiData.latestMetric.numberOfProjects <= i.Maximum
                    ) {
                    
                            let value = updateProperties(colorObject, i.color)
                        return {...colorObject,properties:value}
                    }
                });
            }
        })
    );
    return newData;
}

let colorValue = updateColor();

console.log(colorValue);

value has been updating it on the updateProperties function, but it is not reflected in the newData object. value 一直在updateProperties function 上更新它,但它没有反映在 newData object 中。 still i am getting oldObject, not the new one.我仍然得到 oldObject,而不是新的。

HERE IS THE LINK FOR THAT这是链接

You aren't using the result of newData.map .您没有使用newData.map的结果。 Also you don't need a nested map since all you want to operate on is a specific object.此外,您不需要嵌套的 map,因为您想要操作的只是特定的 object。

What you need is to find that object and update it.您需要找到 object 并更新它。 Make use of Array.prototype.find to find the relevant matching object for state and then update it using the range array by looping over it利用Array.prototype.find为 state 找到相关的匹配 object,然后通过循环使用范围数组对其进行更新

 let ApiData1 = { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "MultiPolygon" }, "properties": { "color": 1, "id": 10, "stateId": 10, "name": "Tamil Nadu", "code": "TN" } }, { "type": "Feature", "geometry": { "type": "MultiPolygon" }, "properties": { "color": 1, "id": 11, "stateId": 11, "name": "Karnataka", "code": "KA" } }, { "type": "Feature", "geometry": { "type": "MultiPolygon" }, "properties": { "color": 1, "id": 12, "stateId": 12, "name": "Pondicherry", "code": "PY" } } ] } let ApiData2 = [ { id: 10, name: "Tamil Nadu", code: "TN", latitude: 29.9964948, longitude: 81.6855882, latestMetric: { stateId: 10, year: 0, numberOfProjects: 1433, } }, { id: 11, name: "Karnataka", code: "KA", latitude: 21.9964948, longitude: 82.6855882, latestMetric: { stateId: 11, year: 0, numberOfProjects: 3500, } }, { id: 12, name: "Pondicherry", code: "PY", latitude: 22.9964948, longitude: 87.6855882, latestMetric: { stateId: 12, year: 0, numberOfProjects: 5500, } } ]; function updateColor() { function updateColorValue(colorJsonObject, colorValue) { let updatedProperties = {...colorJsonObject.properties, color: colorValue }; colorJsonObject.properties = updatedProperties; return {...colorJsonObject }; } function updateProperties(colorJsonObject, colorValue) { let updatedProperties = {...colorJsonObject.properties, color: colorValue }; console.log(updatedProperties) return updatedProperties; } let range = [ { "Minimum": 1, "Maximum": 2000, "color": 1 }, { "Minimum": 2000, "Maximum": 4000, "color": 2 }, { "Minimum": 4000, "Maximum": 6000, "color": 3 } ] let newData = {...ApiData1, features: ApiData1.features.map(colorObject => { const apiData = ApiData2.find(apiData => { if ( colorObject.properties.stateId === apiData.latestMetric.stateId ) { return true; } return false; }); let newValue; range.forEach(i => { if ( apiData.latestMetric.numberOfProjects >= i.Minimum && apiData.latestMetric.numberOfProjects <= i.Maximum ) { let value = updateProperties(colorObject, i.color) newValue = {...colorObject,properties:value} } }); return newValue; }) } return newData; } let colorValue = updateColor(); console.log(colorValue);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM