2

In the below object, I want to increment the value of data[1]'s val by 1, and leave everything unchanged, how can I achieve it?

const state = 
    {
        "data": [{
                "val": 1,
                "other": 10
            },
            {
                "val": 11,
                "other": 100
            },
            {
                "val": 100,
                "other": 1000
            }
        ]
    }

I want the mutated object to be like this-

{
    "data": [{
            "val": 1,
            "other": 10
        },
        {
            "val": 10,
            "other": 100
        },
        {
            "val": 100,
            "other": 1000
        }
    ]
}

I know that I can change the value directly like this- state.data[1].val = state.data[1].val+1, but I want to achieve the same using spread operator, is it possible to achieve it using spread operator? Somthing like this-

const mutatedState = {
        ...state,
        data: [...state.data]
}
1
  • Working with deep objects and immutability can be a real pain so something like lodash's functional programming helpers can make your life much easier. look up: lodash/fp/set Commented Apr 14, 2019 at 18:12

3 Answers 3

4

Get the data out of the object. And use like this

const state = { "data": [{ "val": 1, "other": 10 }, { "val": 11, "other": 100 }, { "val": 100, "other": 1000 } ] }
    
const {data} = state;         
let res = {
            ...state,
            data:[
                    data[0],
                    {...data[1],val:data[1].val+ 1},
                    ...data.slice(2)
                 ]
          }
 
console.log(result)

Sign up to request clarification or add additional context in comments.

Comments

1

You could assign parts of the array/objects.

var object = { data: [{ val: 1, other: 10 }, { val: 10, other: 100 }, { val: 100, other: 1000 }] },
    result = {
        ...object,
        data: Object.assign(
            [...object.data],
            {
                1: Object.assign(
                    {},
                    object.data[1],
                    { val: object.data[1].val + 1 }
                )
            }
        )
    };

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

With a bit help of some functional helpers that is actually quite elegant:

 const mapOne = (index, mapper) => array => array.map((it, i) => i === index ? mapper(it) : it);
 const lens = (key, mapper) => obj => ({ ...obj, [key]: mapper(obj[key]) });

 // somewhere
 this.setState(mapOne(1, lens("val", it => it + 1)));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.