首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在对象数组中过滤对象数组

在对象数组中过滤对象数组
EN

Stack Overflow用户
提问于 2022-11-07 21:45:41
回答 3查看 53关注 0票数 0

我在试着过滤这个json。

这是json

代码语言:javascript
复制
const json = {
  address: "fdqn",
  pDet: [
    {
      pNam: "pnam1",
      pMem: [
        {
          mIP: "1234",  // search this string '1234'
          gp: "gp1"
        }, {
          mIP: "567", 
          gp: "gp2"
        }, {
          mIP: "890", 
          gp: "gp3"
        }
      ]
    },
    {
      pNam: "pnam1",
      pMem: [
        {
          mIP: "4567", 
          gp: "gp5"
        }, {
          mIP: "5674", 
          gp: "gp7"
        }
      ]
    }
  ]
}

我需要使用mIP = "1234"进行过滤,最后的输出应该是。

代码语言:javascript
复制
const json = {
    address: "fdqn",
    pDet: [
      {
        pNam: "pnam1",
        pMem: [
          {
            mIP: "1234", 
            gp: "gp1"
          }
        ]
      }
    ]
  }

我尝试了过滤器和一些,但似乎我需要在过滤器内迭代。如有任何意见将不胜感激。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-11-07 21:57:18

利用flatMap仿真filter_map其他语文中的行为,可以得到如下结果:

代码语言:javascript
复制
const json = {address:"fdqn",pDet:[{pNam:"pnam1",pMem:[{mIP:"1234",gp:"gp1"},{mIP:"567",gp:"gp2"},{mIP:"890",gp:"gp3"}]},{pNam:"pnam1",pMem:[{mIP:"4567",gp:"gp5"},{mIP:"5674",gp:"gp7"}]}]};

const search = "1234";

const result = {
    address: json.address,
    // check if there is any match in this pMem
    pDet: json.pDet.flatMap(({ pMem }) => pMem.some(({ mIP }) => mIP === search)
        ? [pMem.filter(({ mIP }) => mIP === search)] // if there is, return filtered array
        : [] // otherwise, return nothing
    ),
};

console.log(result);

票数 3
EN

Stack Overflow用户

发布于 2022-11-07 22:09:22

您可以像这样使用array.reduce()array.filter()

代码语言:javascript
复制
const json = { address: "fdqn", pDet: [{ pNam: "pnam1", pMem: [{ mIP: "1234", gp: "gp1" }, { mIP: "567", gp: "gp2" }, { mIP: "890", gp: "gp3" }] }, { pNam: "pnam1", pMem: [{ mIP: "4567", gp: "gp5" }, { mIP: "5674", gp: "gp7" }] } ] }

const newJSON = {
    address: json.address,
    pDet: json.pDet.reduce((newArr, obj) => {
        const pMem = obj.pMem.filter(obj2 => obj2.mIP === '1234')
        if (pMem.length) newArr.push({
            pNam: obj.pNam,
            pMem
        })
        return newArr
    }, [])
}

console.log(newJSON)

在一个函数中,它可能如下所示:

代码语言:javascript
复制
const json = { address: "fdqn", pDet: [{ pNam: "pnam1", pMem: [{ mIP: "1234", gp: "gp1" }, { mIP: "567", gp: "gp2" }, { mIP: "890", gp: "gp3" }] }, { pNam: "pnam1", pMem: [{ mIP: "4567", gp: "gp5" }, { mIP: "5674", gp: "gp7" }] } ] }

function filterArray(jsonObj, searchStr) {
    return {
        address: json.address,
        pDet: json.pDet.reduce((newArr, obj) => {
            const pMem = obj.pMem.filter(obj2 => obj2.mIP === search)
            if (pMem.length) newArr.push({
                pNam: obj.pNam,
                pMem
            })
            return newArr
        }, [])
    }
}

const newJSON = filterArray(json, '1234')

console.log( newJSON )

票数 1
EN

Stack Overflow用户

发布于 2022-11-07 22:55:11

类似于来自@猫的答案中的技术,虽然更通用,但我使用了一个filterMap。在我的例子中,我抓取了一个可重用的函数--我手头有。看起来是这样的:

代码语言:javascript
复制
const filterMap = (f, m) => (xs) => xs .flatMap (x => f (x) ? [m (x)] : [])

const searchMIP = ({pDet, ...rest}, query) => ({
  ...rest,
  pDet: filterMap (
    ({pMem}) => pMem .some (({mIP}) => mIP == query),
    ({pMem, ...rest}) => ({...rest, pMem: pMem .filter (({mIP}) => mIP == query)})
  ) (pDet)
})

const obj = {address: "fdqn", pDet: [{pNam: "pnam1", pMem: [{mIP: "1234", gp: "gp1"}, {mIP: "567", gp: "gp2"}, {mIP: "890", gp: "gp3"}]}, {pNam: "pnam1", pMem: [{mIP: "4567", gp: "gp5"}, {mIP: "5674", gp: "gp7"}]}]}

console .log (searchMIP (obj, '1234'))

但我对此并不满意,因为filterMap通常的优点之一是它只扫描一次列表。但是在这里,我们使用some在filter部分执行,在map部分使用filter再次执行。

因此,这里有一种稍微不同的方法,仍然使用flatMap来做类似的事情,但是只过滤一次,并使用结果的length来决定我们是否保留对象:

代码语言:javascript
复制
const searchMIP = ({pDet, ...rest}, query) => ({
  ...rest,
  pDet: pDet .flatMap (
    ({pMem, kids = pMem .filter (({mIP}) => mIP == query), ...rest}) => kids .length ? [({
      ...rest, 
      pMem: pMem .filter (({mIP}) => mIP == query)
    })] : [] 
  )
})

const obj = {address: "fdqn", pDet: [{pNam: "pnam1", pMem: [{mIP: "1234", gp: "gp1"}, {mIP: "567", gp: "gp2"}, {mIP: "890", gp: "gp3"}]}, {pNam: "pnam1", pMem: [{mIP: "4567", gp: "gp5"}, {mIP: "5674", gp: "gp7"}]}]}

console .log (searchMIP (obj, '1234'))
代码语言:javascript
复制
.as-console-wrapper {max-height: 100% !important; top: 0}

这与来自用户@路多芬的答案更相似,但没有可变累加器,而且还是稍微通用一些。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74353280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档