Home > Back-end >  Find the common element with the highest index
Find the common element with the highest index

Time:04-01

I'm trying to refactor a piece of code in a less verbose methods.

Basically I have this array of user skills:

const skills = ['add', 'edit', 'delete', 'secondSkill', 'fourthSkill']

Then I have an array of select options:

const options = [
  {
    label: "First",
    value: "firstSkill"
  },
  {
    label: "Second",
    value: "secondSkill"
  },
  {
    label: "Third",
    value: "thirdSkill"
  },
  {
    label: "Fourth",
    value: "fourthSkill"
  }
];

I'm trying to write a method that:

  • find the common elements between arrays skills and options
  • return ONLY the common element with the biggest index in the options array

For example: in this case I want to return fourthSkill because is the element with the biggest index in my options array.

I came up with something like that:

const findDefaultValue = (selectOptions, userSkills) => {
  const commonItems = selectOptions.filter((opt) =>
    userSkills.includes(opt.value)
  );
  
  const findIndexes = commonItems.map((item) => {
    return selectOptions.indexOf(item);
  });
  const maxIndex = Math.max(...findIndexes);
  return options[maxIndex];
};

It kinda works, but I would like to hear from you if there are shorter ways to do it. Thanks!

CodePudding user response:

You can just return the last item of commonItems, like:

const findDefaultValue = (selectOptions, userSkills) => {
  const commonItems = selectOptions.filter((opt) =>
    userSkills.includes(opt.value)
  );
  
  return commonItems.at(-1);
}

In the future, you'll be able to use findLast, like:

const findDefaultValue = (selectOptions, userSkills) => {
  return selectOptions.findLast((opt) =>
    userSkills.includes(opt.value)
  );
};

CodePudding user response:

Another one solution. One-liner if you don't mind.

const skills = ['add', 'edit', 'delete', 'secondSkill', 'fourthSkill']
const options = [{label: "First",value: "firstSkill"}, {label: "Second",value: "secondSkill"}, {label: "Third", value: "thirdSkill"}, {label: "Fourth",value: "fourthSkill"}];

const result = options.reverse().find(({ value }) => skills.includes(value));

console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}

CodePudding user response:

Since the particular index is not important, and all you need is just one element, you can iterate through a reversed copy of the array and return the first element that matches.

const skills = ['add', 'edit', 'delete', 'secondSkill', 'fourthSkill']
const options = [{label: "First",value: "firstSkill"}, {label: "Second",value: "secondSkill"}, {label: "Third", value: "thirdSkill"}, {label: "Fourth",value: "fourthSkill"}];

const findDefaultValue = (selectOptions, userSkills) => {
    for(const {label, value} of [...selectOptions].reverse()) {
        if( userSkills.includes(value) ) {
            return {label,value};
        }
    }
    return 'NONE FOUND';
};

console.log( findDefaultValue(options, skills) );
/*OUTPUT:
{
  "label": "Fourth",
  "value": "fourthSkill"
}
*/

Alternatively, you can use @AlexandrBelan's one-liner with the caveat of using a copy, so options remains unchanged:

const skills = ['add', 'edit', 'delete', 'secondSkill', 'fourthSkill']
const options = [{label: "First",value: "firstSkill"}, {label: "Second",value: "secondSkill"}, {label: "Third", value: "thirdSkill"}, {label: "Fourth",value: "fourthSkill"}];

const findDefaultValue = 
    (selectOptions, userSkills) => 
    [...selectOptions].reverse().find(({value}) => userSkills.includes(value));

console.log( findDefaultValue(options, skills) );
/*OUTPUT:
{
  "label": "Fourth",
  "value": "fourthSkill"
}
*/

  • Related