使用 map 进行嵌套数组处理以产生字符串结果

Nested array processing using map to produce a string result

给定以下数组(嵌套),我不确定如何使用 map 遍历这些嵌套数组以产生以下结果。

const qry = [
  {
    qryNm: "A",
    qryResult: "",
    qryWhere: [
        {
            qryReqs: [
                {
                    col: "name",
                    op: "=",
                    colVal: "tom"
                },
                {
                    col: "country",
                    op: "=",
                    colVal: "germany"
                }   
            ]
        },
        {
            qryReqs: [
                {
                    col: "name",
                    op: "=",
                    colVal: "sally"
                },
                {
                    col: "country",
                    op: "=",
                    colVal: "italy"
                }   
            ]
        }        
    ]
  },
  {
    qryNm: "B",
    qryResult: "",
    qryWhere: [
        {
            qryReqs: [
                {
                    col: "name",
                    op: "=",
                    colVal: "kirk"
                },
                {
                    col: "country",
                    op: "=",
                    colVal: "sweeden"
                }   
            ]
        },
        {
            qryReqs: [
                {
                    col: "name",
                    op: "=",
                    colVal: "grace"
                },
                {
                    col: "country",
                    op: "=",
                    colVal: "usa"
                }   
            ]
        }        
    ]
  }
]

我需要遍历上述数组并产生以下结果:

(name = 'tom' and
 country = 'germany')
or
(name = 'sally' and
 country = 'italy')

并将此值分配给 qry 数组中的 qryResult,对于 qryNm,即:

qryResult = "(name = 'tom' and country = 'germany') or (name = 'sally' and country = 'italy')";

显然,qryResult 需要针对 qry 数组中的每个数组元素进行处理。

因此对于数组 qryWhere 中的每个 qryReqs,将其分解为“或”条件。

有了三级数组,我不确定如何实现我的结果。

我意识到我需要使用:

qry.map((q, i) => (
  // unsure from here
))

任何 help/guidance 都很好。

这是实现类似结果的一种方法

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)

您可以将问题分解成几个部分。首先,您需要将以下对象 (req):

{col: "name", op: "=", colVal: "sally"}

进入字符串:

name = 'sally'

这可以通过使用 template literal(或字符串连接)并通过访问对象的 colopcolVal 属性来完成:

`${req.col} ${req.op} '${req.colVal}'`

现在您可以将单个对象转换为字符串,您可以使用上面的模板文字映射最里面的 (qryReqs) 数组:

qryReqs: [ 
  { col: "name", op: "=", colVal: "sally" }, 
  { col: "country", op: "=", colVal: "italy" } 
]

此映射函数类似于:

qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`)

这会生成一个字符串数组:

["name = 'sally'", "country = 'italy'"]

在您的输出中,您希望其采用以下形式:(string[0] and string[1] and string[2] and ... and string[n])。我们可以join这个数组中的字符串使用.join(' and ')得到一个字符串,然后把那个字符串用括号():

包起来
`(${qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`).join(' and ')})`

这样做会为我们提供一个用括号中的每个内部对象用“and”连接的字符串:

"(name = 'sally' and country = 'italy')"

由于我们想对 qryWhere 内的所有对象执行上述映射操作,我们可以映射 qryWhere 并将上述模板文字 + join() 逻辑应用于每个对象:

qryWhere.map(
  ({qryReqs}) => `(${qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`).join(' and ')})`
)

执行上述操作得到:

["(name = 'tom' and country = 'germany')", "(name = 'sally' and country = 'italy')"]

有了这个结果,我们需要用“或”子句将它们连接在一起以匹配您的输出,这可以通过将上述结果数组与 .join(" or "):

连接来完成
qryWhere.map(
  ({qryReqs}) => `(${qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`).join(' and ')})`
).join(' or ')

然后您可以在 qry 数组上执行外部 .map() 以对数组中的所有对象执行此转换:

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);

如果您想向对象添加额外的 属性 qryResult,可以通过在地图回调中创建一个新对象 {},然后使用传播来完成语法 ... 将所有(可枚举的)键从当前对象复制到新对象。然后,您可以将新的 qryResult 添加到具有上述映射值的新对象:

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((qryObj) => ({
  ...qryObj,
  qryResult: qryObj.qryWhere.map(
    ({qryReqs}) => `(${qryReqs.map(req => `${req.col} ${req.op} '${req.colVal}'`).join(' and ')})`
  ).join(' or ')
}));

console.log(result);
console.log(result[0].qryResult);