0

I have an array of objects which i receive from a db:

[{
    key: 'PRODUCT',
    item_key: 'ITEM_01',
    sequence: 1
  },
  {
    key: 'STORE',
    item_key: 'STORE_01',
    sequence: 2
  }
]

I want to create a Map from it but the condition is, i want the item_key to be the map key, and only the corresponding array element which matches the item_key will be the value of that map key. So the map looks like

{
  'ITEM_01' => [{
    key: 'PRODUCT',
    item_key: 'ITEM_01',
    sequence: 1
  }],
  'STORE_01' => [{
    key: 'STORE',
    item_key: 'STORE_01',
    sequence: 2
  }]
}

I've kept the value of map keys as an array because there can be more values matching the map key in future. How can i do this?

P.S. by Map i don't mean the array function map, but the JS/TS Map

3
  • there can be more values matching the map key in future It might be a good idea to update your example showing this. As this is pretty much fundamental to the question, as your will likely want reduce not map.. Commented Jul 5, 2022 at 9:18
  • @Keith I meant the JS/TS Map object, not the array function. Added it in the edit. Commented Jul 5, 2022 at 9:29
  • That's not what I'm talking about, your wanting the Value to be an array, because the source could have multiple keys with the same key, so your result is will want reducing reduce,. Your example data does not show a duplicate, so I was pointing out it would be a good idea to show it, as it's a pretty fundamental aspect of your output. Commented Jul 5, 2022 at 9:38

4 Answers 4

4

Use reduce to create an object, if the key exists in the object then push to the array, otherwise create an array and push the item:

const items = [{
    key: 'PRODUCT',
    item_key: 'ITEM_01',
    sequence: 1
  },
  {
    key: 'STORE',
    item_key: 'STORE_01',
    sequence: 2
  }
]

const result = items.reduce((obj, item) => {
  if (!obj.hasOwnProperty(item.item_key)) {
    obj[item.item_key] = [];
  }
  
  obj[item.item_key].push(item);

  return obj;
}, {});

console.log(result);

Here is an exmaple with Map:

const map = new Map();

const items = [{
    key: 'PRODUCT',
    item_key: 'ITEM_01',
    sequence: 1
  },
  {
    key: 'STORE',
    item_key: 'STORE_01',
    sequence: 2
  }
]

items.forEach(item => {
  if (map.has(item.item_key)) {
    map.get(item.item_key).push(item);
  } else {
    map.set(item.item_key, [item])
  }
});

console.log(Object.fromEntries(map))

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

3 Comments

This works, but i want to set it in a Map, the global object. I didn't mean to use the array function map as i've added it in an update to the question, i wanted the result inside a Map.
@Matt_crud I have added an example with map, using forEach.
The whole if statement could be reduced to a single line: map.get(item.item_key)?.push(item) ?? map.set(item.item_key, [item]);
1

You can use the Map constructor

const arr = [{
    key: 'PRODUCT',
    item_key: 'ITEM_01',
    sequence: 1
  },
  {
    key: 'STORE',
    item_key: 'STORE_01',
    sequence: 2
  }
];

const myMap = new Map();
arr.forEach(obj => myMap.set(obj.item_key, obj));

console.log(Object.fromEntries(myMap));

4 Comments

can you edit this to use Map's set function? I have to initialize an empty Map as a global variable and set it accordingly at runtime.
Updated, is this what you wanted?
@Matt_crud This does not handle duplicate, the reason for value been an array, or was that part not important after all?.
@Keith that wasn't important.
1
    /**
     * return the value of map keys as an array
     * @param list data from DB
     * @param map new map or any map you already have
     */
    function saveToMap(list: any[], map: Map<string, any[]>) {
        list.forEach(obj => {
            if (map.has(obj.key)) {
                map.get(obj.key)?.push(obj)
            } else {
                map.set(obj.key, [obj])
            }
        })
        return [...map.keys()]
    }
    
    const list = [
        {
            key: "PRODUCT",
            item_key: "ITEM_01",
            sequence: 1,
        },
        {
            key: "STORE",
            item_key: "STORE_01",
            sequence: 2,
        },
    ]
    // new map or any map you already have
    const map = new Map()
    const res = saveToMap(list, map)
    console.log(res)

1 Comment

Can someone tell me why my answer doesn't have a "Run code sinppet" button ?
0

You reduce it.

let arr =[{
    key: 'PRODUCT',
    item_key: 'ITEM_01',
    sequence: 1
  },
  {
    key: 'STORE',
    item_key: 'STORE_01',
    sequence: 2
  }
]

let result = arr.reduce((prev, curr) => {
   prev[curr.item_key] = curr
   return prev;
}, {})

console.log(result);

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.