Home > Enterprise >  For..of loop only runs once
For..of loop only runs once

Time:08-31

I have a for..of loop as my callback function for a filter function. The issue Im having is that the object I am testing with in my callback is only iterated over once so only the first value is applied to the filter. Is there a way to force my for loop to iterate the number of times as the length of the object? I know with array for loops this is possible but not sure about objects.

Heres an example:

const search = {
  Condition: "Allergies",
  ProductName: "Acetaminophen"
}

const meds = 
  [ { Active      : false
    , Condition   : [ 'Allergies'] 
    , DaysSupply  : 0
    , Doseform    : 'Tablet'
    , ProductName : 'Acetaminophen 650 mg tablet, extended release'
    , Protocol    : 'PATIENT COMMUNICATION:  Price $10.  100 tablets'
    , Quantity    : 100
    } 
  , { Active      : false
    , Condition   : [ 'COVID-19 Symptoms'] 
    , DaysSupply  : 0
    , Doseform    : 'Tablet'
    , ProductName : 'Acetaminophen 650 mg tablet, extended release'
    , Protocol    : 'PATIENT COMMUNICATION: Price is $10.  100 tablets'
    , Quantity    : 100
    } 
  , { Active      : false
    , Condition   : [ 'Headaches (Migraine & Tension)'] 
    , DaysSupply  : 0
    , Doseform    : 'Tablet'
    , ProductName : 'Acetaminophen 650 mg tablet, extended release'
    , Protocol    : 'PATIENT COMMUNICATION: Price is $10.  100 tablets'
    , Quantity    : 100
    } 
  , { Active      : false
    , Condition   : [ 'Allergies'] 
    , DaysSupply  : 0
    , Doseform    : 'Capsule'
    , ProductName : 'Amoxicillin 500 mg capsule'
    , Protocol    : 'PATIENT COMMUNICATION: Price is $20- 21 capsules'
    , Quantity    : 21
    } 
  ] 

const comparedtosearch = (medication, searchParams) => {
  for (let [key, value] of Object.entries(searchParams)) {
    // do(es) the object(s) contain the search value
    if (key === "Condition") {
      const includesSearch = (item) => item.toLowerCase().includes(value.toLowerCase())
      // conditions are arrays 
      return medication[key].some(includesSearch)
    } else if (key != "Condition") {
      return medication[key].toLowerCase().includes(value.toLowerCase())
    }
  }
}

const handleSearch = (searchParams) => {
  // clean copy of the medications (formularies)
  const medications = [...meds]
  const formFiltered = medications.filter((med) => comparedtosearch(med, searchParams))

  console.log(formFiltered)
  //setLoading(false)
}

handleSearch(search)
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

My expected Result would be the item that has matching values for all the values passed in the search. All of the values in the meds objects could be added to the search object because this object is built from user input fields and passed in as the user edits the fields. I understand I may need to create more tests inside the callback function to handle int values but for now it handles strings and arrays. Im just stuck on the loop only using the first value in the search object.

CodePudding user response:

You need to loop through the SearchParams and return false if any of them do not match. After looping through all of them successfully, return true.

const search = {Condition: "Allergies", ProductName: "Acetaminophen"}
 
 const meds = [{Active: false,
Condition: ["Allergies"],
DaysSupply: 0,
Doseform: "Tablet",
ProductName: "Acetaminophen 650 mg tablet, extended release",
Protocol: "PATIENT COMMUNICATION:  Price $10.  100 tablets",
Quantity: 100},{Active: false,
Condition: ["COVID-19 Symptoms"],
DaysSupply: 0,
Doseform: "Tablet",
ProductName: "Acetaminophen 650 mg tablet, extended release",
Protocol: "PATIENT COMMUNICATION: Price is $10.  100 tablets",
Quantity: 100},{Active: false,
Condition: ["Headaches (Migraine & Tension)"],
DaysSupply: 0,
Doseform: "Tablet",
ProductName: "Acetaminophen 650 mg tablet, extended release",
Protocol: "PATIENT COMMUNICATION: Price is $10.  100 tablets",
Quantity: 100},{Active: false,
Condition: ["Allergies"],
DaysSupply: 0,
Doseform: "Capsule",
ProductName: "Amoxicillin 500 mg capsule",
Protocol: "PATIENT COMMUNICATION: Price is $20- 21 capsules",
Quantity: 21}]

 
 
 const comparedtosearch = (medication, searchParams) => {
        for (let [key, value] of Object.entries(searchParams)){
            // do(es) the object(s) contain the search value
            if(key === "Condition"){
                const includesSearch = (item) => item.toLowerCase().includes(value.toLowerCase())
                // conditions are arrays 
                if (!medication[key].some(includesSearch)) {
                  return false
                }
            } else if(key != "Condition"){
                if (!medication[key].toLowerCase().includes(value.toLowerCase())) {
                  return false
                }
            }
        }
        return true
    }

    const handleSearch = (searchParams) => {
    // clean copy of the medications (formularies)
      const medications = [...meds]
      const formFiltered = medications.filter((med) => comparedtosearch(med, searchParams))

      console.log(formFiltered)
      //setLoading(false)
    }
    
    handleSearch(search)

  • Related