-2

I have list of statuses where not started is the minimum , followed by submitted and last is complete.

So if we apply the logic on the data since there are 2 status on the current array of object below which are "Not Started" and "Submitted" so the function should return Not Started because not started is the min.

If there is only 1 item in an array then get the only status as a result.

How do we filter the array of objects and get the min based on the order in statuses array. Thanks for any idea.

#currentCode

  getMin(id:number , key:string) {
    
    let data = [
      {
          "id": 14,
          "status": "Submitted",
  
      },
      {
          "id": 15,
          "status": "Not Started",
      }
  ]

    let min = Math.min(...data.map(item => item.status));

    console.log('result' , min)

  }

#order of statuses

  statuses: any[] = [
    { viewValue: 'Not Started', value: 1 },
    { viewValue: 'Submitted', value: 2 },
    { viewValue: 'Complete', value: 3 },
  ]

#sample array of objects - result Not Started

data = [
    {
        "id": 14,
        "status": "Submitted",

    },
    {
        "id": 15,
        "status": "Not Started",
    }
]

#sample array of objects - result Submitted

  data = [
        {
            "id": 14,
            "status": "Submitted",
    
        },
         {
            "id": 17,
            "status": "Complete",
        }
    ]

#sample array of objects - result Complete , since there is only 1 get the only status

  data = [
         {
            "id": 17,
            "status": "Complete",
        }
    ]
Tim Launders
  • 249
  • 1
  • 10

2 Answers2

1

You need to look up the status from data in your statuses array.

const data = [
      {
          "id": 14,
          "status": "Submitted",

      },
       {
          "id": 17,
          "status": "Complete",
      }
  ];

const statuses = [
    { viewValue: 'Not Started', value: 1 },
    { viewValue: 'Submitted', value: 2 },
    { viewValue: 'Complete', value: 3 },
  ]

let min = Math.min(...data.map(item => statuses.find(st => st.viewValue === item.status).value));
let minStatus = statuses.find(st => st.value === min).viewValue;

console.log(minStatus);
James
  • 20,957
  • 5
  • 26
  • 41
0

A straightforward solution is to simply sort the array by statuses value, which then gives you access to the complete ordering, and the entire object for each position. Here first mapping the statuses array to an object keyed by viewValue to directly access status values.

const data = [
  { "id": 14, "status": "Submitted", },
  { "id": 17, "status": "Complete", },
  { "id": 15, "status": "Not Started", },
  { "id": 15, "status": null, }
];

const statuses = [
  { viewValue: 'Not Started', value: 1 },
  { viewValue: 'Submitted', value: 2 },
  { viewValue: 'Complete', value: 3 },
];
const statusMap = Object.fromEntries(statuses
  .map(({ viewValue, value }) => [viewValue, value])
);

const sorted = data
  .filter(d => Object.hasOwn(statusMap, d.status))
  .sort((a, b) => statusMap[a.status] - statusMap[b.status]);

const min = sorted.at(0);
const max = sorted.at(-1);

console.log('min:', min.status);
console.log('max:', max.status);

// or the complete objects
console.log({ min, max })

Edit

Added a filter() call before sorting to remove datum that don't have a status that appears in statusMap using Object.hasOwn. This also makes the original spread redundant since filter() returns a new array thus avoiding mutation of the original data array with the sort() call.

pilchard
  • 12,414
  • 5
  • 11
  • 23
  • how do we handle for example there is status in an object where value is null ? , it would cause error on the function – Tim Launders Aug 31 '22 at 22:16
  • 1
    Do you not want `null` statuses included? If so just filter them out. – pilchard Aug 31 '22 at 22:22
  • yes , it should not include empty or null status – Tim Launders Aug 31 '22 at 22:25
  • error Property 'hasOwn' does not exist on type 'ObjectConstructor'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2022' or later.ts(2550) – Tim Launders Aug 31 '22 at 22:30
  • 1
    sounds like you're transpiling to older js. You can use `statusMap.hasOwnProperty(d.status)` or `d.status in statusMap` but you might want to output more modern js from TS. see: [How do I check if an object has a specific property in JavaScript?](https://stackoverflow.com/questions/135448/how-do-i-check-if-an-object-has-a-specific-property-in-javascript) – pilchard Aug 31 '22 at 22:31