Home > Net >  Comparing 2 arrays and fetch values to see if array 1 is greater than array 2
Comparing 2 arrays and fetch values to see if array 1 is greater than array 2

Time:03-22

I am still in the midst of learning React and Javascript and have came to a roadblock with my current project.

Project goal I am trying to map through two array of objects, and check if a certain property matches. if recommendedSkillTree.skills.skill === currentSkills.skill, I would then like to check if recommendedSkillTree.skills.level > currentSkills.level. if the above condition matches, or if currentSkills.skill do not have the skills in the recommendedSkillTree Data, the skill will then show up in a red text. Else, green text.

What I have done I have tried mapping between the 2 arrays to check if currentSkills.skill === recommendedSkillTree.skills.skill.

  const skillMatch = recommendedSkillTree.filter((skillRecommended) =>
    currentSkills.some((skillCurrent) => skillRecommended.skills.skill === skillCurrent.skill)
  );
.
.
.
  return (
   <div>
     {recommendedSkillTree.map((item, i) => (
            <div key={item.id}>
              <div
                style={{
                  color: !skillMatch[i] ? "red" : "green", 
                }}
              >
                {item.skill}
              </div>
            </div>
          ))}
   </div>


By doing so, I am able to churn out an output where skills that are present in currentSkills are shown in green, and those that are not in it are shown in red.

Next I would like to go one step deeper, and tried to compare the skill level of the present skills, and if they fall short of the recommended level, the text would then show in red.

  const levelGap = recommendedSkillTree.map((recommendedLevel) =>
    currentSkills.some((levelCurrent) => recommendedLevel.level > levelCurrent.level)
  );

By doing so, I would be expecting an output of

[true, false, true, true, true, true, true, true, true]

instead I've got:

[true, true, true, true, false, true, true, false, false]

I am unable to see which part have went wrong. Would greatly appreciate if any seniors in this field would guide me along.

Data 1

const recommendedSkillTree = [
  {
    id: "1",
    role: "Paladin",
    skills: [
      {
        id: "1",
        skill: "Attack",
        level: "3",
      },
      {
        id: "2",
        skill: "Block",
        level: "3",
      },
      {
        id: "3",
        skill: "Taunt",
        level: "3",
      },
      {
        id: "4",
        skill: "Heal",
        level: "4",
      },
      {
        id: "5",
        skill: "Group Heal",
        level: "2",
      },
      {
        id: "6",
        skill: "Double Attack",
        level: "4",
      },
      {
        id: "7",
        skill: "Ultimate",
        level: "3",
      },
      {
        id: "8",
        skill: "Defense Up",
        level: "2",
      },
      {
        id: "9",
        skill: "Attack Up",
        level: "2",
      },
    ],
  },
];
export default recommendedSkillTree;

Data 2

const currentSkills = [
  {
    id: "1",
    skill: "Attack",
    level: "2",
  },
  {
    id: "2",
    skill: "Block",
    level: "3",
  },
  {
    id: "3",
    skill: "Taunt",
    level: "2",
  },
  {
    id: "4",
    skill: "Heal",
    level: "3",
  },
  {
    id: "5",
    skill: "Final Slash",
    level: "3",
  },
];
export default currentSkills;

Thank you in advance for your time, and I do apologize if my way of asking questions are not up to community standard as this is my first time posting on here. I do not really have anyone around me to ask questions on since I am fully self-taught and no one around me is in the tech field. Thank you so much.

CodePudding user response:

This may be one possible solution to achieve the desired objective.

Code Snippet

const isGreenOrRed = (reco, curr) => (
  reco.skills.map(re => (
    curr.some(({skill}) => skill === re.skill)
    ? curr.find(({skill}) => skill === re.skill)['level'] >= re.level
      ? 'green'
      : 'red'
    : 'red' 
  ))
);

const recommendedSkillTree = [
  {
    id: "1",
    role: "Paladin",
    skills: [
      {
        id: "1",
        skill: "Attack",
        level: "3",
      },
      {
        id: "2",
        skill: "Block",
        level: "3",
      },
      {
        id: "3",
        skill: "Taunt",
        level: "3",
      },
      {
        id: "4",
        skill: "Heal",
        level: "4",
      },
      {
        id: "5",
        skill: "Group Heal",
        level: "2",
      },
      {
        id: "6",
        skill: "Double Attack",
        level: "4",
      },
      {
        id: "7",
        skill: "Ultimate",
        level: "3",
      },
      {
        id: "8",
        skill: "Defense Up",
        level: "2",
      },
      {
        id: "9",
        skill: "Attack Up",
        level: "2",
      },
    ],
  },
];

const currentSkills = [
  {
    id: "1",
    skill: "Attack",
    level: "2",
  },
  {
    id: "2",
    skill: "Block",
    level: "3",
  },
  {
    id: "3",
    skill: "Taunt",
    level: "2",
  },
  {
    id: "4",
    skill: "Heal",
    level: "3",
  },
  {
    id: "5",
    skill: "Final Slash",
    level: "3",
  },
];

console.log(isGreenOrRed(recommendedSkillTree[0], currentSkills).join(", "));

const SomeComp = ({getColor, ...props}) => (
   <div>
     {recommendedSkillTree[0].skills.map((item, i) => (
            <div key={item.id}>
              <div
                style={{
                  color: getColor[i] 
                }}
              >
                {item.skill}
              </div>
            </div>
          ))}
   </div>
);

ReactDOM.render(
  <div>
    <h4>Demo UI</h4>
    <SomeComp getColor={isGreenOrRed(recommendedSkillTree[0], currentSkills)}/>
  </div>,
  document.getElementById('rd')
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

Explanation

  • this uses the same logic as attempted by OP in the question
  • fixes some of the issues faced

Below solution employs an alternative approach to get the same result.

Code Snippet

const isGreenOrRed = (needle, haystack) => (
    haystack.some(({skill}) => skill === needle.skill)
    ? haystack.find(({skill}) => skill === needle.skill)['level'] >= needle.level
      ? 'green'
      : 'red'
    : 'red' 
);

const recommendedSkillTree = [
  {
    id: "1",
    role: "Paladin",
    skills: [
      {
        id: "1",
        skill: "Attack",
        level: "3",
      },
      {
        id: "2",
        skill: "Block",
        level: "3",
      },
      {
        id: "3",
        skill: "Taunt",
        level: "3",
      },
      {
        id: "4",
        skill: "Heal",
        level: "4",
      },
      {
        id: "5",
        skill: "Group Heal",
        level: "2",
      },
      {
        id: "6",
        skill: "Double Attack",
        level: "4",
      },
      {
        id: "7",
        skill: "Ultimate",
        level: "3",
      },
      {
        id: "8",
        skill: "Defense Up",
        level: "2",
      },
      {
        id: "9",
        skill: "Attack Up",
        level: "2",
      },
    ],
  },
];

const currentSkills = [
  {
    id: "1",
    skill: "Attack",
    level: "2",
  },
  {
    id: "2",
    skill: "Block",
    level: "3",
  },
  {
    id: "3",
    skill: "Taunt",
    level: "2",
  },
  {
    id: "4",
    skill: "Heal",
    level: "3",
  },
  {
    id: "5",
    skill: "Final Slash",
    level: "3",
  },
];

console.log(recommendedSkillTree[0].skills.map(it => isGreenOrRed(it, currentSkills)).join(", "));

const SomeComp = () => (
   <div>
     {recommendedSkillTree[0].skills.map(item => (
            <div key={item.id}>
              <div
                style={{
                  color: isGreenOrRed(item, currentSkills)
                }}
              >
                {item.skill}
              </div>
            </div>
          ))}
   </div>
);

ReactDOM.render(
  <div>
    <h4>Demo UI - Alternate Approach</h4>
    <SomeComp />
  </div>,
  document.getElementById('rd')
);
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

Explanation

  • This pushes the validation at the individual skill object level
  • Thus, re-using the existing .map iteration happening in the JSX

CodePudding user response:

Here's an example using Lodash map. You can try play around with the check function to get the desired result.

const recommendedSkillTree = [{
  id: "1",
  role: "Paladin",
  skills: [{
      id: "1",
      skill: "Attack",
      level: "3",
    },
    {
      id: "2",
      skill: "Block",
      level: "3",
    },
    {
      id: "3",
      skill: "Taunt",
      level: "3",
    },
    {
      id: "4",
      skill: "Heal",
      level: "4",
    },
    {
      id: "5",
      skill: "Group Heal",
      level: "2",
    },
    {
      id: "6",
      skill: "Double Attack",
      level: "4",
    },
    {
      id: "7",
      skill: "Ultimate",
      level: "3",
    },
    {
      id: "8",
      skill: "Defense Up",
      level: "2",
    },
    {
      id: "9",
      skill: "Attack Up",
      level: "2",
    },
  ],
}];

const currentSkills = [{
    id: "1",
    skill: "Attack",
    level: "2",
  },
  {
    id: "2",
    skill: "Block",
    level: "3",
  },
  {
    id: "3",
    skill: "Taunt",
    level: "2",
  },
  {
    id: "4",
    skill: "Heal",
    level: "3",
  },
  {
    id: "5",
    skill: "Final Slash",
    level: "3",
  },
];

var result = [];

function check(skill) {
  var found = _.find(currentSkills, function(o) {
    return o.skill === skill.skill;
  });

  if (found) {
    result.push(found.level >= skill.level);
  } else {
    result.push(false);
  }
}

_.map(recommendedSkillTree[0].skills, check);

console.log(result);
<script src="https://lodash.com/vendor/cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

  • Related