Home > Blockchain >  Find the best match in an array
Find the best match in an array

Time:05-11

I have got the following array:

let x = [
  { name: "Bad", value: 2 },
  { name: "Critical", value: 1 },
  { name: "High", value: 5 },
  { name: "Medium", value: 5 },
];

The expectation is to look for "Critical" first, if the array has it, return that, else look for "High" then look for "Medium" and so on.

CodePudding user response:

You can store the priorities in an array and then loop over the array and for every priority check if there's an object and whenever an object is found, return it. If the entire priorities array is exhausted then return null (or whatever you want).

const arr = [
    { name: "Bad", value: 2 },
    { name: "Critical", value: 1 },
    { name: "High", value: 5 },
    { name: "Medium", value: 5 },
  ],
  priorities = ["Critical", "High", "Medium", "Bad"],
  search = (arr, priorities) => {
    for (let p of priorities) {
      const obj = arr.find(({ name }) => name === p);
      if (obj) {
        return obj;
      }
    }
    return null;
  };

console.log(search(arr, priorities));

You can also sort the array based on the priority.

  • Create a Map that stores the priorities.
  • Sort arr based on the priorities stored in the map.

const arr = [
    { name: "Bad", value: 2 },
    { name: "Critical", value: 1 },
    { name: "High", value: 5 },
    { name: "Medium", value: 5 },
  ],
  priorities = new Map([
    ["Critical", 4],
    ["High", 3],
    ["Medium", 2],
    ["Bad", 1],
  ]),
  sortedArr = [...arr].sort(
    (a, b) => priorities.get(b.name) - priorities.get(a.name)
  );

console.log(sortedArr);

CodePudding user response:

let value = x.find(x => x.name == "Critical") 
  || x.find(x => x.name == "High")
  || x.find(x => x.name == "Medium") ...

CodePudding user response:

First, define the order in which you want to look for items, then use that to sort the items in the array. Lastly, find based on all the items in your sort order. The first match will be returned, since the items are sorted.

const x = [{name: 'Bad',value: 2}, {name: 'High', value: 5}, {name: 'Medium', value: 5}, {name: 'Critical', value: 1}],
      order = ['Critical','High','Medium'],
      //sort according to above order
      output = x.sort(
          ({name:na},{name:nb}) => 
          order.findIndex(v => v === na) - order.findIndex(v => v === nb)
      )
      //Now find items matching name in order
      .find( ({name}) => order.includes(name) );
      
console.log( output );

NOTE

  • Since your data is already sorted in the desired order, I moved the element with name = "Critical" to the end of the array.
  • If the data will always be sorted according to the priority you want to find the items, then no sorting is needed.

CodePudding user response:

This will iterate over the array once until it finds the highest value and break the loop once it finds that value. Maximum number of iterations is N where N is x.length;

let x = [{name: 'Bad',value: 2},
{name: 'Critical', value: 1},
{name: 'High', value: 5},
{name: 'Medium', value: 5}]

function findVal(arr) {
  let returnVal = null;
  for (let i = 0; i < arr.length && returnVal === null; i  ) {
    switch (arr[i].name) {
      case 'Critical':
        returnVal = arr[i];
        break;
      case 'High':
        returnVal = arr[i];
        break;
      case 'Medium':
        returnVal = arr[i];
        break;
      case 'Low':
        returnVal = arr[i];
        break;
      default:
        break;
    }
  }
  return returnVal;
}

findVal(x);

Note: It would be far simpler to designate a numerical value to the array values so that you could determine the severity simply by using the highest/lowest value rather than string matching

  • Related