0

I have a requirement to modify a JSON to a JSON having the values in a SQL query format. To better explain.

{
    "Assets": {
        "ASSOCIATES_NAME": ["David", "Philip"],
        "CAR_NAME": ["Verron"]
    }
  , "Product":{"SELLER_NAME": ["XXXXX"]}
}

The result should be having the json values as an sql query leaving the keys as it is. So the resulting query will be:

{
  Assets: "(ASSOCIATES_NAME = 'David' OR ASSOCIATES_NAME = 'Philip') AND CAR_NAME = 'Verron'", 
  Product: "SELLER_NAME = 'XXXXX'"
}

I tried something but I couldn't figure it out well. Below it is:

console.log(Object.entries(a).map(x => {return {
  [x[0]]: `${Object.keys(x[1])} = '${Object.values(x[1])}'`,
  }}))

However I still need to figure out how to group individual values of an array. Any elegant ES6 based solution to this?. Please folks help me out on this. TIA

5
  • Consider parsing the JSON string? JSON.parse. Also, I'm not sure why you would need regex in this situation. Commented Dec 23, 2020 at 11:11
  • Yes I parsed the string. however the problem lies with the values.... I tried numerous ways like Object.entries, values etc. Commented Dec 23, 2020 at 11:13
  • 1
    Please may you share those previous tries. Making a simple minimal reproducible example of each try is best. Commented Dec 23, 2020 at 11:14
  • Just a warning: Please be very careful of SQL Injection attacks when handling raw SQL queries in the frontend. Commented Dec 23, 2020 at 11:19
  • @evolutionxbox shared. please have a look Commented Dec 23, 2020 at 11:23

2 Answers 2

3

Here's one way to do it, using Array.reduce to iterate over the outer object properties and Array.map over the inner object properties to generate the OR and AND expressions:

const json = `{
    "Assets": {
        "ASSOCIATES_NAME": ["David", "Philip"],
        "CAR_NAME": ["Verron"]
    }
  , "Product":{"SELLER_NAME": ["XXXXX"]}
}`
const params = JSON.parse(json);

const whereItems = Object.entries(params)
  .reduce((c, [k, v]) => {
    c[k] = Object.entries(v)
      .map(([param, value]) => '(' + value.map(v => param + " = '" + v + "'").join(' OR ') + ')')
      .join(' AND ');
    return c;
  }, {});
console.log(whereItems);

Note that it does produce unnecessary () around the single comparisons (e.g. (SELLER_NAME = 'XXXXX')), if you really want to get rid of them just condition the addition of those characters on value.length > 1.

Sign up to request clarification or add additional context in comments.

5 Comments

(You could use a template string to avoid the backslashes?)
@evolutionxbox indeed. that's a lot cleaner; I've edited it in. thanks.
Oh good heavens. Thanks a lot @Nick. You saved my day. Just made a minor change as suggested by @evolutionxbox ${value.map(v => param + " = '" + v + "'").join(" OR ")}
Yeah.... @Nick what are your thoughts when the value is not array but just a string if in case of a single value. like ["Verron"] would be just "Verron"
You'd need to edit the code that dealt with value to check if it was a string or an array, possibly simplest to just turn it into an array if it's not.
1

upvote for @nik's answer, here is just another way for beginners.

f3 = function(key, arr){
var result = arr.map(function(e) {
  return(`${key}='${e}'`)
})
if(result.length > 1)
  return(`(${result.join(' AND ')})`)
else
  return(result)
}

f2 = function(json) {
  var result = []
  for(const key in json) {
    result.push(f3(key, json[key]))
  }
  return(result.join(' OR '))
}

f = function(json) {
  var result = {}
  for(const key in json) {
    result[key] = f2(json[key])
  }
  return(result)
}

call f over your json

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.