Best way design and generate unique strings from an array of objects for mapping

228 Views Asked by At

The problem I am trying to solve is how best to generate a unique string from a set of question/answer strings.

So say an end user fills out a questionnaire and answers the following:

   [
       {
           "is there a problem": "yes"
       },
       {
           "what is it?": "product is damaged"
       },
       {
           "do you want a refund?": "yes"
       }
   ]

I need to generate a string that represents these questions and answers and then map that to a templateId to send a templated message to.

I thought about simply running a foreach and adding all the questions and responses together but the issue there is what if the questions and answers change or additional questions are added that we are not interested in for sending message purposes.

Should I use something like find or a hashtable type of look up instead so I am only picking out the questions I need. I am a bit worried about performance here too but it shouldn't be a big deal as this set of questions/answers should remain relatively small.

I was also wondering about this string -> templateId mapping, what is the best way to store this information, a simple object works fine?

Clarification:

It doesn't have to be unique or be a hashmap. Basically we have email templates in the backend to send messages. In the frontend we need to figure out which email template to use given the set of responses to the questions. So my simple solution was to append the questions/answers together to generate a string, i.e "isThereProblemYesWhatisIt?ProductDamagedDoyouwantaRefund?Yes"

i.e Available templates in the backend:

productDamaged
productLost

Mapping created in the front end.

"isThereProblem?YesWhatisIt?ProductDamagedDoyouwantaRefund?Yes" : 
"productDamaged"

Thanks

2

There are 2 best solutions below

4
danh On BEST ANSWER

With a small set of questions and answers, an enumeration is feasible and maintainable. Something like this:

const userSubmission = [{
    "is there a problem": "yes"
  },
  {
    "what is it?": "product is damaged"
  },
  {
    "do you want a refund?": "yes"
  }
]

const userSubmission2 = [{
    "is there a problem": "yes"
  },
  {
    "what is it?": "product is damaged"
  },
  {
    "do you want a refund?": "no"
  }
]

const templates = {
  "is there a problem-yeswhat is it?-product is damageddo you want a refund?-yes": "templateForDamagedAndRefundWanted",
  "is there a problem-yeswhat is it?-product is damageddo you want a refund?-no": "templateForDamagedAndRefundNotWanted"
}

function keyFromSubmission(submission) {
  return submission.reduce((acc, obj) => {
    let [key, value] = Object.entries(obj)[0]
    acc += `${key}-${value}`
    return acc
  }, "")
}


const key = keyFromSubmission(userSubmission)
console.log(templates[key])

console.log("\nOr, with a different user submission...")
const key2 = keyFromSubmission(userSubmission2)
console.log(templates[key2])

EDIT

You can plan for textual changes to questions and answers by adding a level of indirection. With this, questions, answers and their variants are represented symbolically.

const questions = [{
    questionId: "q1",
    text: "what is the problem?",
    answers: [{
      answerId: "a1",
      text: "product was broken"
    }, {
      answerId: "a2",
      text: "product didn't arrive"
    }]
  },
  {
    questionId: "q2",
    text: "do you want a refund?",
    answers: [{
      answerId: "a1",
      text: "yes"
    }, {
      answerId: "a2",
      text: "no"
    }]
  }
]

const userSubmission = [{
    "what is the problem?": "product didn't arrive"
  },
  {
    "do you want a refund?": "yes"
  }
]

function userSubmissionAsSymbols(submission) {
  return submission.map(s => {
    let [key, value] = Object.entries(s)[0]
    let question = questions.find(q => q.text === key)
    let answer = question.answers.find(a => a.text === value)
    return `${question.questionId}-${answer.answerId}`
  })
}

console.log(userSubmissionAsSymbols(userSubmission))

With this, you do the same thing as before, mapping the keys derived from the q/a values to templates. In this version, though, the text presented to the user can be changed arbitrarily.

6
Edward On

From your updated response, you should take a look at react conditional rendering which is very similar to what you want to complete.

On your frontend you should map each question to an index in an array such as.

["is there a problem", "what is it?", "do you want a refund?"]

That way you'll know that index 0 of the results will ALWAYS be "is there a problem" and then you can send clean info to the backend where you will be able to understand where everything is like:

["yes", "product is damaged", "yes"]

In your backend you will be able to run switch statements or if statements. This is completely up to you but it will look like:

if(data[0] === "yes" && data[1] === "product is damaged") {
   //return email template 1
}
else if(data[0] === "yes" && data[1] === "product is lost") {
   //return email template 2
}