Aleks
Aleks

Reputation: 101

Extracting objects out of arrays

I want to map from this:

companies: {
  apples: {
   Q7: {
    price: 1,
   },
   Q6: {
    price: 1,
   },
  peaches: {
   Q7: {
    price: 1,
   },
   Q6: {
    price: 1,
   },
 },
};

to this:

{ "companies": {
    "apples": [
        {
            "name": "Q7",
            "price": 1
        },{
            "name": "Q6",
            "price": 1
        }
    ],
    "peaches": [
        {
            "name": "Q7",
            "price": 1
        },{
            "name": "Q6",
            "price": 1
        }
    ]
  }
}

How I am trying to achieve this: I have a selector which gives me the companies object and then I map over it and assemble my object but I don't get it quite right.

This is my function:

const weaponProducts = Object.entries(getCompanies(state)).map(([companyType, companies]) => {
        const prod = Object.entries(companies).map(([key, companies]) => {
           return {
               name: key,
               price: companies.price
           }
        });
        return {
            [companyType]: prod
        };
    });

getCompanies(state) returns the following object:

{
    "companies": {
        "apples": {
            "Q7": {
                "price": 1
            },
            "Q6": {
                "price": 1
            }
        },
        "peaches": {
            "Q7": {
                "price": 1
            },
            "Q6": {
                "price": 1
            }
        }
    }
}

The result of the function is the following. But as explained I want it to look like the second code section of my post.

[
  {
    "apples": [
      {
        "name": "Q7",
        "price": 1
      },
      {
        "name": "Q6",
        "price": 1
      },
    ]
  },
  {
    "peaches": [
      {
        "name": "Q7",
        "price": 1
      },
      {
        "name": "Q6",
        "price": 1
      },
    ]
  }
]

Upvotes: 0

Views: 82

Answers (3)

Rajneesh
Rajneesh

Reputation: 5308

You can also take entries and then map the objects accordingly.

var companies = { apples: { Q7: { price: 1, }, Q6: { price: 1, }, }, peaches: { Q7: { price: 1, }, Q6: { price: 1, } }};

const result = (inputObj) =>
  Object.fromEntries(
    Object.entries(inputObj).map(([key, obj]) => [
      key,
      Object.entries(obj).map(([name, val]) => ({ name, ...val })),
    ])
  );

console.log(result(companies));

Upvotes: 1

richytong
richytong

Reputation: 2452

If you're down to try something new, here's a different way to express the desired transformation using a library I authored.

const x = { companies: { apples: { Q7: { price: 1, }, Q6: { price: 1, }, }, peaches: { Q7: { price: 1, }, Q6: { price: 1, }, }, } }

const { pipe, fork, map, tap, get } = rubico

const y = map(map(pipe([
  Object.entries,
  map(fork({
    name: get(0),
    price: get([1, 'price']),
  })),
])))(x)

console.log(JSON.stringify(y, null, 2))
<script src="https://unpkg.com/rubico/index.js"></script>

Upvotes: 0

Ethan Lipkind
Ethan Lipkind

Reputation: 1156

since your desired output is an object, not an array, you should use reduce instead of map:

let companies = {
  apples: {
   Q7: {
    price: 1,
   },
   Q6: {
    price: 1,
   },
  },
  peaches: {
   Q7: {
    price: 1,
   },
   Q6: {
    price: 1,
   },
 },
}

let fruit = Object.keys(companies)
let output = fruit.reduce((output, currentFruit) => {
  output[currentFruit] = Object.keys(companies[currentFruit]).map(q => {
    return { name: q, price: companies[currentFruit][q].price }
  })
  return output
}, {});

console.log(output);

(I think there was a syntax error in your companies object, I corrected in the snippet)

Upvotes: 2

Related Questions