Given the following array (nested), I'm unsure how to loop through these nested arrays using map to produce the below result.
const qry = [
{
qryNm: "A",
qryWhere: [
{
qryReqs: [
{
col: "name",
op: "=",
colVal: "tom"
},
{
col: "country",
op: "=",
colVal: "germany"
}
]
},
{
qryReqs: [
{
col: "name",
op: "=",
colVal: "sally"
},
{
col: "country",
op: "=",
colVal: "italy"
}
]
}
]
}
]
I need to loop through the above array and produce the following result:
(name = 'tom' and
country = 'germany')
or
(name = 'sally' and
country = 'italy')
and basically assign this to a value, say:
result = "(name = 'tom' and country = 'germany') or (name = 'sally' and country = 'italy')";
So for every qryReqs
within the array qryWhere
, break this as an "OR" condition.
Having the three level of arrays, I'm unsure how to achieve my result.
I realise that I need to use:
qry.map((q, i) => (
// unsure from here
))
Any help/guidance would be great.
CodePudding user response:
Here is one way to achieve a similar result
const qry = [{
qryNm: 'A',
qryWhere: [{
qryReqs: [{
col: 'name',
op: '=',
colVal: 'tom',
},
{
col: 'country',
op: '=',
colVal: 'germany',
},
],
},
{
qryReqs: [{
col: 'name',
op: '=',
colVal: 'sally',
},
{
col: 'country',
op: '=',
colVal: 'italy',
},
],
},
],
}, ]
const result = qry
.map(obj1 =>
obj1.qryWhere
.map(
obj2 =>
`( name = '${obj2.qryReqs[0].colVal}' and country = '${obj2.qryReqs[1].colVal}' )`
)
.join(' or ')
)
.join(' or ')
console.log(result)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can break the problem down into parts. First, you need to turn the below object (req
):
{col: "name", op: "=", colVal: "sally"}
into the string:
name = 'sally'
This can be done by using a template literal (or string concatenation) and by accessing the col
, op
and colVal
properties from your object:
`${req.col} ${req.op} '${req.colVal}'`
Now that you can convert the individual objects into strings you can map your innermost (qryReqs
) array using the above template literal:
qryReqs: [
{ col: "name", op: "=", colVal: "sally" },
{ col: "country", op: "=", colVal: "italy" }
]
The mapping function for this would look something like:
qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`)
This produces an array of strings:
["name = 'sally'", "country = 'italy'"]
In your output, you want this to be in the form of: (string[0] and string[1] and string[2] and ... and string[n])
. We can join the strings in this array using .join(' and ')
to get a string, and then wrap that string in parenthesis ()
:
`(${qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`).join(' and ')})`
Doing this gives us a string joined with "and"s for each inner object wrapped in parenthesis:
"(name = 'sally' and country = 'italy')"
Since we want to perform the above mapping operation on all of your objects inside of qryWhere
, we can map qryWhere
and apply the above template literal join() logic to each object:
qryWhere.map(
({qryReqs}) => `(${qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`).join(' and ')})`
)
Doing the above gives us:
["(name = 'tom' and country = 'germany')", "(name = 'sally' and country = 'italy')"]
With this result, we need to join them together with an "or" clauses to match your output, which can be done by joining the above array of results with .join(" or ")
:
qryWhere.map(
({qryReqs}) => `(${qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`).join(' and ')})`
).join(' or ')
You can then perform an outer .map()
on your qry
array to perform this conversion for all objects in your array:
const qry = [{ qryNm: "A", qryWhere: [{ qryReqs: [{ col: "name", op: "=", colVal: "tom" }, { col: "country", op: "=", colVal: "germany" } ] }, { qryReqs: [{ col: "name", op: "=", colVal: "sally" }, { col: "country", op: "=", colVal: "italy" } ] } ] }];
const results = qry.map(({qryWhere}) => qryWhere.map(
({qryReqs}) => `(${qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`).join(' and ')})`
).join(' or '));
const [res] = results; // if you want to extract the first result
console.log(results);
console.log(res);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>