0

I have the following interface

export class Items {
  items: Map<string, string>;
  createdBy: string;
  deliveredBy: string;
}

and I am getting my data the following day from the API call (Sorry I am not sure how to make a Stackblitz to represent the same data so pasting from console)

Map(2) {"ItemOne" => "ItemOneData1000", "ItemTwo" => "ItemTwoData2000"}
Map(2) {"ItemOne" => "ItemOneData1001", "ItemTwo" => "ItemTwoData3000"}
Map(2) {"ItemOne" => "ItemOneData1002", "ItemTwo" => "ItemTwoData4000"}
Map(2) {"ItemOne" => "ItemOmeData1003", "ItemTwo" => "ItemTwoData5000"}
Map(2) {"ItemOne" => "ItemOneData1004", "ItemTwo" => "ItemTwoData6000"}
Map(2) {"ItemOne" => "ItemOneData1230", "ItemTwo" => "ItemTwoData7000"}
Map(2) {"ItemOne" => "ItemOneData1430", "ItemTwo" => "ItemTwoData8000"}
Map(2) {"ItemOne" => "ItemOneData1340", "ItemTwo" => "ItemTwoData9000"}
Map(2) {"ItemOne" => "ItemONeData1210", "ItemTwo" => "ItemTwoData1000"}
Map(2) {"ItemOne" => "ItemONEData1430", "ItemTwo" => "ItemTwoData1100"}
Map(2) {"ItemOne" => "ItemOnEData1334", "ItemTwo" => "ItemTwoData1200"}
Map(2) {"ItemOne" => "ItemOnEData1555", "ItemTwo" => "ItemTwoData1300"}
Map(2) {"ItemOne" => "ItemOnEData9999", "ItemTwo" => "ItemTwoData1400"}
Map(2) {"ItemOne" => "ItemoNEData8888", "ItemTwo" => "ItemTwoData1500"}
Map(2) {"ItemOne" => "ItemONeData1550", "ItemTwo" => "ItemTwoData1600"}

I want to create and array for EACH key in a Map<string, string>.

My logic :

if(key) <-- to check for duplicate keys
  push(values) <-- push each key value to create an array

code:

myArr = [];
this.service
  .getItems(itemId)
  .pipe()
  .subscribe((val) => {
    const allData = this.val;
    allData.map((eachItem) => {
      eachItem.items.forEach((value, key) => {
        if(key){
            myArr.push(value)
        }
      });
    });
  });

}

This leads to creating array for each key value but does not create a one array for EACH key. Is there an efficient way to create arrays ?

Thank you very much for your time and help.

0

1 Answer 1

1

It sounds like you want to build a single new map keyed by the keys in the maps in the items property of the objects in the array you get from your service, where the value for each key is an array of the values in those maps.

If so, nested loops is a straightforward way to do it:

const result = new Map();
for (const {items} of arrayFromService) {
    for (const [key, value] of items) {
        const arr = result.get(key);
        if (arr) {
            arr.push(value);
        } else {
            result.set(key, [value]);
        }
    }
}

Live Example (you might want to look in the real browser console rather than the in-snippet one, because the in-snippet one doesn't show Map instances in a useful way [as of this writing]):

const arrayFromService = [
    {items: new Map([["ItemOne", "ItemOneData1000"], ["ItemTwo", "ItemTwoData2000"]])},
    {items: new Map([["ItemOne", "ItemOneData1001"], ["ItemTwo", "ItemTwoData3000"]])},
    {items: new Map([["ItemOne", "ItemOneData1002"], ["ItemTwo", "ItemTwoData4000"]])},
    {items: new Map([["ItemOne", "ItemOmeData1003"], ["ItemTwo", "ItemTwoData5000"]])},
    {items: new Map([["ItemOne", "ItemOneData1004"], ["ItemTwo", "ItemTwoData6000"]])},
    {items: new Map([["ItemOne", "ItemOneData1230"], ["ItemTwo", "ItemTwoData7000"]])},
    {items: new Map([["ItemOne", "ItemOneData1430"], ["ItemTwo", "ItemTwoData8000"]])},
    {items: new Map([["ItemOne", "ItemOneData1340"], ["ItemTwo", "ItemTwoData9000"]])},
    {items: new Map([["ItemOne", "ItemONeData1210"], ["ItemTwo", "ItemTwoData1000"]])},
    {items: new Map([["ItemOne", "ItemONEData1430"], ["ItemTwo", "ItemTwoData1100"]])},
    {items: new Map([["ItemOne", "ItemOnEData1334"], ["ItemTwo", "ItemTwoData1200"]])},
    {items: new Map([["ItemOne", "ItemOnEData1555"], ["ItemTwo", "ItemTwoData1300"]])},
    {items: new Map([["ItemOne", "ItemOnEData9999"], ["ItemTwo", "ItemTwoData1400"]])},
    {items: new Map([["ItemOne", "ItemoNEData8888"], ["ItemTwo", "ItemTwoData1500"]])},
    {items: new Map([["ItemOne", "ItemONeData1550"], ["ItemTwo", "ItemTwoData1600"]])},
];
const result = new Map();
for (const {items} of arrayFromService) {
    for (const [key, value] of items) {
        const arr = result.get(key);
        if (arr) {
            arr.push(value);
        } else {
            result.set(key, [value]);
        }
    }
}
console.log(result);

The resulting array has ItemOne with the value:

["ItemOneData1000", " ItemOneData1001", " ItemOneData1002", " ItemOmeData1003", " ItemOneData1004", " ItemOneData1230", " ItemOneData1430", " ItemOneData1340", " ItemONeData1210", " ItemONEData1430", " ItemOnEData1334", " ItemOnEData1555", " ItemOnEData9999", " ItemoNEData8888", " ItemONeData1550"]

and itemTwo with the value:

["ItemTwoData2000", " ItemTwoData3000", " ItemTwoData4000", " ItemTwoData5000", " ItemTwoData6000", " ItemTwoData7000", " ItemTwoData8000", " ItemTwoData9000", " ItemTwoData1000", " ItemTwoData1100", " ItemTwoData1200", " ItemTwoData1300", " ItemTwoData1400", " ItemTwoData1500", " ItemTwoData1600"]
Sign up to request clarification or add additional context in comments.

4 Comments

Hi T.J, Thank you so much for the code. Just one confusion, why is const arr = result.get(key); not undefined since the result map does not have keys inside of it currently. Also, when I run the code snipped, it seems to be empty
@JeffBenister - Glad if that helps! arr is undefined the first time each key is encountered. That's what the if (arr) test is for -- if we've seen the key before, arr will be an array, which is truthy, so we go into the if block; if we haven't seen the key before, arr will be undefined and we'll go into the else.
For anyone confused about why {} shows up in the StackSnippets console, it is because the console is not able to show the structure of the Map object.
I understand, sorry I made a mistake when I copied the code and was running an into issue. Thank you again.

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.