我已经花了一段时间思考这个问题,以为也许是时候在这里发布了。

我有一个复杂的对象结构,可以在任何级别的深度都有一个嵌套项。这是一个例子:

 {
    resourceType: 'QuestionnaireResponse',
    item: [
      {
        linkId: 'Floors',
        answer: []
      },
      {
        linkId: 'KID',
        answer: [
          {
            valueBoolean: false
          }
        ]
      },
      {
        linkId: 'Age',
        answer: [
          {
            valueString: '≥30 Years'
          }
        ]
      },
      {
        linkId: 'UnicornGroup',
        item: [
          {
            linkId: 'DoYouLikeUnicorns',
            answer: [{valueBoolean: true}]
          },
          {
            linkId: 'DoYouLikeFHIR'
          }
        ],
        answer: []
      }
    ]
  }


我想结束一个看起来像这样的对象:

{
    resourceType: 'QuestionnaireResponse',
    item: [
      {
        linkId: 'KID',
        answer: [
          {
            valueBoolean: false
          }
        ]
      },
      {
        linkId: 'Age',
        answer: [
          {
            valueString: '≥30 Years'
          }
        ]
      },
      {
        linkId: 'UnicornGroup',
        item: [
          {
            linkId: 'DoYouLikeUnicorns',
            answer: [{valueBoolean: true}]
          }
        ]
      }
    ]
  }


那就是我想过滤掉具有空答案数组的项目对象,而没有具有非空答案数组的嵌套对象。

这是我所拥有的,但不起作用:

var res = fItems.filter(function f(o) {
  if (o.answer && o.answer.length > 0) {
    return true
  } else {
    if(o.item){
      return f(o.item);
    }
  }
});


我创建了一个REPL Here。我们在项目中使用ramda,因此如果解决方案使用ramda也可以。感谢您的时间。

最佳答案

我认为filter()实际上是错误的工具,因为它无法轻松处理要递归过滤item数组的情况。为此,您需要将items属性设置为新的过滤后的数组,然后最终对原始数组进行变异。也许更好的方向是通过添加所需项而不是过滤来构建一个新数组。在不是带有子项数组的组的项中,情况很简单-如果它们有答案,则只需添加即可。但是,这些项目必须以不同的方式处理。也许这样会有所帮助:



let obj = {resourceType: 'QuestionnaireResponse',item: [{linkId: 'Floors',answer: []},{linkId: 'KID',answer: [{valueBoolean: false}]},{linkId: 'Age',answer: [{valueString: '≥30 Years'}]},{linkId: 'UnicornGroup',item: [{linkId: 'DoYouLikeUnicorns',answer: [{valueBoolean: true}]},{linkId: 'DoYouLikeFHIR'}],answer: []}]}

function filterAnswers(item_arr){
    return item_arr.reduce((arr, current) => {
        // deal with groups
        if (current.item && current.item.length){
            let item = filterAnswers(current.item)
            if (item.length) {
                let ret_obj = {linkId: current.linkId, item:item}
                arr.push(ret_obj)
            }
        }
        // deal with the simple case
        else if(current.answer && current.answer.length)
            arr.push(current)
        return arr
    }, [])
}
let filtered_items = filterAnswers(obj.item)
console.log(filtered_items)





为了使代码简单,我假装(也许)复合组的answers属性始终为空。从示例中尚不清楚这些项目是否可能具有answers和空的item数组,或者同时具有itemanswer。无论哪种方式,都只是测试并在推送之前将其添加到对象中。

09-16 16:52