Home > Back-end >  JavaScript how to set conditions to make for-loop and .include() filter correctly?
JavaScript how to set conditions to make for-loop and .include() filter correctly?

Time:04-10

Confused with how to check whether keys in a dictionary matches elements in two or one of the two other arrays then add matched dictionary entries into strings correctly..

The code:

target = {
  'A': 1,
  'B': 1,
  'D': 2,
  'L': 2
}

let a_include = ["A","B","C","D","E","F","G"];
let b_include = ["H","I","J","K","L","M","N","O","P","Q","R"];

a_string = ""
b_string = ""

if (target.length == 0) {
  a_string  = "None for a"
  b_string  = "None for b"
} else {
  for(const i of Object.keys(target)) {
  const verify = a_include.includes(i)
  const verify2 = b_include.includes(i)
  if (verify && !verify2) {
    a_string  = i   ": "   target[i]   "\n";
    b_string  = "None for B";
  } else if (!verify && verify2){
    a_string  = "None for A"
    b_string  = i   ": "   target[i]   "\n"
  } else {
    a_string  = "None for A"
    b_string  = "None for B"
   }
 }
}

Basically the code supposed to check if the dictionary target's keys matches any elements in array a_include or b_include then add to either a_string or b_string (With dictionary's key values too)

expected function:

  • The code adds "None for A" or B to both a&b_stringif no entry in target.

  • If not empty then it runs a for-loop on target's keys and compare it with a_include & b_include

  • If all keys have matches in both arrays,entries include in a_include then add to a_string, otherwise add to b_string

  • If all keys matched in a_include but none for b_string , then add entries to a_string but "None for B" for b_string, reversibly add "None for A" to a_string if no matches to a_include.

  • If target is not empty and no matches for both arrays, then add "None" to both a and b_string

Currently if target = {'A': 1,'B': 1,'D': 2,'L': 2}, the output string produces:

a_string's output:  "A: 1              b_string's ouput:  "None for BNone for BNone for BL: 2
                     B: 1                                 "
                     D: 2
                     None for A"

But what I am trying to output is:

a_string's output:  "A: 1              b_string's ouput:  "L: 2"
                     B: 1                                 
                     D: 2"

I tried simply remove "None for A/B" to prevent it from wrongly add "None for A/B" into strings, but then the "None for" output won't be produce too if the dictionary has no keys match for one of the arrays:

If target = {'A': 1,'B': 1,'D': 2}, the output string produces:

a_string's output:  "A: 1              b_string's ouput:  "None for BNone for BNone for B"
                     B: 1                                 
                     D: 2
                     "

Instead of:

a_string's output:  "A: 1              b_string's ouput:  "None for B"
                     B: 1                                 
                     D: 2
                     "

So how to set conditions/loop to make the a and b_string produce the expected output?

*this is actually use for Discord embed so "MessageEmbed field values may not be empty" will occur if remove "None for ..." and leave the strings empty

Thanks for reading.

CodePudding user response:

So according to my debugging of your code. The loop goes through every key of the target dictionary and the conditional statement checks for every key. That's where the problem is you don't want the conditional statement to check for unnecessary conditions. For example -

Here,

for(const i of Object.keys(target)) {  
  const verify = a_include.includes(i) 
  const verify2 = b_include.includes(i)  
  if (verify && !verify2) { 
    a_string  = i   ": "   target[i]   "\n"; 
    b_string  = "None for B"; 
  } else if (!verify && verify2){
    a_string  = "None for A"
    b_string  = i   ": "   target[i]   "\n"
  } else {
    a_string  = "None for A"
    b_string  = "None for B"
   }
}

Suppose , target = { "A": 1, "B": 1, "D": 2, "L": 2 }

The loop will check for A, B, D, and L and it will confirm the first three,i.e, A, B, and D as a_string but it will also check for L and assign it to b_string.

The problem is for a_string the last key,i.e, L is a rogue key and thus will assign "None for A", even if the a_string has already some text in it, and similarly for b_string the first three keys are rouge.

So you get the idea of how your program is working, now towards the solution -

if (verify && !verify2) { 
    a_string  = i   ": "   target[i]   "\n"; 
    b_string  = "None for B";  // Remove this line
  } else if (!verify && verify2){
    a_string  = "None for A"
    b_string  = i   ": "   target[i]   "\n" // Remove this line
  } else {
    a_string  = "None for A"
    b_string  = "None for B"
  }

Instead of checking for the rogue keys there, add a new conditional statement after the loop like this -

{...}
    if (verify && !verify2) {
        a_string  = i   ": "   target[i]   "\n";
        // b_string  = "None for B";
    } else if (!verify && verify2) {
        // a_string  = "None for A"
        b_string  = i   ": "   target[i]   "\n"
    } else {
        a_string  = "None for A"
        b_string  = "None for B"
    }
{...}

//after the loop

if (a_string.length === 0) {
    a_string = "None for a";
} 
if (b_string.length === 0) { // edited
    b_string = "None for b"
}

This works because after the loop ends the condition checks if either a_string or b_string is empty and if it is empty, it will assign the new changes.

There are more solutions to this particular problem, but I have tried to do it in a simple and understandable way.

  • Related