kyserslick
kyserslick

Reputation: 591

Create a new map from an array of object with similar id in Typescript

I'm trying to create a map> from a list of objects that have similar ids in typescript, but I don't get the correct way to do. I know that in lodash something like so is doable but can't get it to work. This what I have tried

let's say I have list of colors like so:

 [
    {
        "Id": "1",
        "color": "red",
        "ref": "tr"
    },
    {
        "Id": "1",
        "color": "blue",
        "ref": "gt",
    },
    {
        "Id": "2",
        "color": "red",
        "ref": "tt"
    },
 ]

I'm trying to construct a map like so

[
  1: [
      {
        "Id": "1",
        "color": "red",
        "ref": "tr"
      },
      {
        "Id": "1",
        "color": "blue",
        "ref": "gt",
      }
     ],
  2: [
      {
        "Id": "2",
        "color": "red",
        "ref": "tt"
      }
     ]
]

this is what I tried so far:

const colorsMap: Map<string, Array<Color>> = new Map<string, Array<Color>>();
let colorLists: Array<Color> = [];
colors.forEach(function (value, i) {
            if (value[i - 1]) {
                if (colors[i - 1].id=== value.gblId) {
                    const color = new Color(value.styleId, value.color, value.ref);
                    colorLists.push(gblRowValue);
                } else {
                    const color = new Color(value.styleId, value.color, value.ref);
                    colorLists= new Array<Color>();
                    colorLists.push(color);
                }
            }
            colorsMap.set(value.id, colorLists);
        });

The result is in each array I get only one value:

    [
      1: [
          {
           "Id": "1",
           "color": "blue",
           "ref": "gt",
          }
         ],
      2: [
          {
           "Id": "2",
           "color": "red",
           "ref": "tt"
          }
         ]
     ]

Upvotes: 0

Views: 3611

Answers (3)

Marc Wissler
Marc Wissler

Reputation: 134

In case you can use es6 features, you could use the following small snippet, which does not require the huge lodash library:

let colors = [
    {
        "Id": "1",
        "color": "red",
        "ref": "tr"
    },
    {
        "Id": "1",
        "color": "blue",
        "ref": "gt",
    },
    {
        "Id": "2",
        "color": "red",
        "ref": "tt"
    },
];
 
let orderedColors = colors.reduce((returnArray, color) => {
     if(!returnArray[color.Id]){
        returnArray[color.Id] = [];   
     }
     returnArray[color.Id].push(color);
     return returnArray;
 },[]);

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 191976

You can use lodash's _.groupBy() to achieve that result:

const data = [{"Id":"1","color":"red","ref":"tr"},{"Id":"1","color":"blue","ref":"gt"},{"Id":"2","color":"red","ref":"tt"}];

const result = _.groupBy(data, 'Id');

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Upvotes: 1

user310988
user310988

Reputation:

array.forEach provides three parameters to the callback.

currentValue

The value of the current element being processed in the array.

index

The index of the current element being processed in the array.

array

The array that forEach() is being applied to.

You're using value and i, which are currentValue and index.

So if (value[i - 1]) { means if (currentValue[index - 1]) { which doesn't make much sense to me.

I think you just want to use the currentValue, something like this.

interface Color {
  Id: string;
  color: string;
  ref: string;
};

let colors: Color[] = [{
  "Id": "1",
  "color": "red",
  "ref": "tr"
},
{
  "Id": "1",
  "color": "blue",
  "ref": "gt",
},
{
  "Id": "2",
  "color": "red",
  "ref": "tt"
}];

let colorMap = new Map<string, Color[]>();

colors.forEach((color) => {
    let colorsArray = colorMap.get(color.Id) || [];
    colorsArray.push(color);

    colorMap.set(color.Id, colorsArray)
});

let colorId1Index0 = colorMap.get("1")[0];
let colorId1Index1 = colorMap.get("1")[1];
let colorId2Index0 = colorMap.get("2")[0];

console.log(`${colorId1Index0.color} ${colorId1Index0.ref}`);
console.log(`${colorId1Index1.color} ${colorId1Index1.ref}`);
console.log(`${colorId2Index0.color} ${colorId2Index0.ref}`);

The console logs:

red tr
blue gt
red tt

Here's it working on the TypeScript Playground.

Upvotes: 0

Related Questions