1

I have an Object with a lot of keys. I need to convert this object to an array of objects but in such a way where I can still access the values for each object by the key.

I want to go from:

{'A': 123, 'B': 453, 'C': 4132}

To:

[{'A': 123}, {'B': 453}, {'C': 4132}]

I want to be able to access the values with a key such as 'A' or 'B' to return 123 and 453 respectively.

I am using Redux and currently my reducer looks like so:

const contextReducer = (state=null, action) => {
    switch(action.type){
        case 'CONTEXTUALIZE':
            state =  Object.values(action.payload)
            state = state.filter(o => (o === state[0] || o === state[3]))
            state = Object.assign(...state)
            console.log(state)
            return state
        default:
            return state
    }
}

export default contextReducer

I have tried using Object.values(state) again right before the return but this gives me an array of items like so:

['A', 123, 'B', 453, 'C', 4132]
1
  • 1
    If you turn it into an array of objects you can't access the objects inside it with keys, but only with numeric indexes. Commented Aug 23, 2019 at 5:50

2 Answers 2

5

If you want to render the state object, or parts of it, in a sort of drop-down style way, you can keep the state object as is and iterate over the keys and values of state when rendering and pass each key-value pair to a child component.

For example:

render() {
    // ... get `state` from redux

    return (
        <div>
            { Object.keys(state).map(key => (
                <MyComponent key={ key } stateKey={ key } stateValue={ state[key] }/>
            ) }
        </div>
    )
}

Note: We're using both the props key and stateKey because the key prop is the special prop for identity in React, and stateKey will be the one used inside of MyComponent.

Original Answer:

Instead of trying to iterate over the values of the state object (with Object.values(state)), you can use the keys, with Object.keys(state), and then access each value using the key with state[key]. Iterate over the keys with a map call and convert each key to an object containing the single key and its corresponding value.

Object.keys(state).map(key => ({[key]: state[key]}))

Result:

[ { A: 123 }, { B: 453 }, { C: 4132 } ]
Sign up to request clarification or add additional context in comments.

14 Comments

This works, thank you very much, but what is the best way to now access the values within each object in the new array of objects? I'd like to be able to access them by key name
@Alex If you want to access the values by key, you won't be able to directly with this array, so you'd be better off sticking with the original object. However, you could make use of the find method of the array, but note that this has a time complexity of O(n) compared to O(1) for accessing values in an object by their keys, but if the array isn't too big, that isn't really an issue. Does that seem like what you're after?
[ { A: 123 }, { B: 453 }, { C: 4132 } ].find(value => value[key] )
@HenryWoody well the array is not super massive, approximately 200 items. Since I cannot access the array by key by keeping it as an object because Objects are not valid as React child. So I am not sure what else to do. I'm not sure how I can really use the find method for arrays when I am trying to render values from my object. This does not seem like a very readable options.
@Alex okay so that's why you wanted the array, so you can pass each sub object (originally key/value pair) to a different component. Then I'd suggest a somewhat similar approach of leaving state as is, but then in your render method, iterate over the values, but pass key/value to the component. For example Object.keys(state).map(key => <MyComponent objKey={ key } objValue={ state[key] }/>). Seem more like what you're after?
|
1

What you're trying to achieve is unfortunately not directly possible. Arrays in JS can only be accessed by integer indices.

I don't know the specifics of why you need this behavior, but I would advise you to store an object in Redux and then create function, which can transform it into shape you want.

Using your example above that would be:

state = {'A': 123, 'B': 453, 'C': 4132}

const objectAsArrayOfEntries = (obj) => 
      (Object.entries(obj).map(entry => {entry[0]: entry[1]})

Here I used Object.entries() function, which returns an array of [key, value] arrays, which gives a close representation of what you're looking for.

1 Comment

Well the reason I am trying to do this is because I want to be able to render very specific values based on a key from my object. The object contains all the data I fetch from an API. I am unsure of a better way to do this but I'm sure there has to be.

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.