-3

I have one map. Checking consecutive keys values on the map, I need to segregate keys & insert into a new array.

let map = new Map<string, string>();
map.set("SUNDAY", "1");
map.set("MONDAY", "2");
map.set("TUESDAY", "2");
map.set("WEDNESDAY", "4");
map.set("THURSDAY", "5");
map.set("FRIDAY", "5");
map.set("SATURDAY", "9");

Expected Output should be like this:

[{
      day: "SUNDAY",
      value: "1"
    },
    {
      day: "MONDAY-TUESDAY",
      value: "2"
    },
    {
      day: "WEDNESDAY",
      value: "4"
    },
    {
      day: "THURSDAY-FRIDAY",
      value: "5"
    },
    {
      day: "SATURDAY",
      value: "9"
    }
  ];
2
  • 1
    The question is underspecified as it's unclear how you want to combine days. The example leaves it open whether the aggregated keys are a range (e.g., "Monday-Wednesday") or just a joined array (e.g., "Monday-Tuesday-Wednesday"). Commented Apr 14, 2019 at 13:56
  • @IngoBürk aggregated keys are a range (e.g., "Monday-Wednesday") Commented Apr 14, 2019 at 14:28

1 Answer 1

2

You could reduce the entries of the Map and group them based on the value. If the current value is already present in the accumulator, append a - and the current day to the object. Else, add a new key to the accumulator. Then use Object.values() to return the values of the accumulator as an array

const map = new Map([["SUNDAY","1"],["MONDAY","2"],["TUESDAY","2"],["WEDNESDAY","4"],["THURSDAY","5"],["FRIDAY","5"],["SATURDAY","5"]]);

const merged = [...map].reduce((acc, [day, value]) => {
  if(acc[value])
    acc[value].day += `-${day}`
  else
    acc[value] = { day, value };
  
  return acc
}, {});

const output = Object.values(merged);

console.log(output)

Update:

If typescript doesn't allow you to spread the Map inside an array, you can set downlevelIteration to true in tsconfig (TypeScript and Iterator: Type 'IterableIterator' is not an array type)

You could also use Map#forEach to do the same thing. Also, if you want the day to be a range of days, you could use another variable called 'previousValue'. If the previousValue is same as current value, split the day which already exists at - and take the first value. Then append the current day

let map = new Map([["SUNDAY","1"],["MONDAY","2"],["TUESDAY","2"],["WEDNESDAY","4"],["THURSDAY","5"],["FRIDAY","5"],["SATURDAY","5"]]);
let merged = {}, previousValue;

map.forEach((value, day) => {
  if(previousValue === value)
    merged[value].day = `${merged[value].day.split('-')[0]}-${day}`
  else
    merged[value] = { day, value };
  
  previousValue = value;
})

const output = Object.values(merged)

console.log(output)

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

8 Comments

You missed combining days MONDAY-TUESDAY and THURSDAY-FRIDAY
My angular code is giving error like: Type 'Map<string, string>' is not an array type or a string type.
@Suman which line exactly? If it's the [...map] line, try using [...map.entries()]`
Yes. I already tried with entries. Its giving error like : Type 'IterableIterator<[string, string]>' is not an array type or a string type.
@Suman You might have to tweak tsconfig to use this TypeScript and Iterator: Type 'IterableIterator<T>' is not an array type (I'll add an answer which doesn't involve spreading the Map)
|

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.