【问题标题】:Filtering Array of objects with array of strings to get result with '&&' clause使用字符串数组过滤对象数组以使用“&&”子句获取结果
【发布时间】:2018-02-13 16:42:01
【问题描述】:

我有一个与位置相关的数据,它来自不同的 api,需要用于根据位置选择过滤另一组数据。

let locationData= [
            {
            "Name": "Olympics",
            "Problem Type": "Access",
            "LS_ID": "421"
        },
        {
            "Name": "Olympics",
            "Problem Type": "Route Issue",
            "LS_ID": "420"
        },
        {
            "Name": "Olympics",
            "Problem Type": "Tools",
            "LS_ID": "420"
        },
        {
            "Name": "Olympics",
            "Problem Type": "Access",
            "LS_ID": "420"
        },
        {
            "Name": "Olympics",
            "Problem Type": "Tools",
            "LS_ID": "422"
        }       
    ]

需要过滤的主数据是

 let mainData=
 [
 {
  "SiteType": "Outdoor",
  "ID": "421", 
  "Name": "Olympics"     
},
 {

  "SiteType": "Indoor",
  "ID": "420", 
  "Name": "Olympics"     
},
 {

  "SiteType": "International",
  "ID": "422", 
  "Name": "Olympics"    
},
 {

  "SiteType": "Local",
  "ID": "423",  
  "Name": "Olympics"    
}
]

我们有一个多选字段,我们将在其中选择'问题类型'选项(例如:Access、Tools、No Entry、Route Issue等) p>

所以在选择时,我们会得到像 ['Access','Tools']

这样的字符串数组

要求是显示同时具有 ('Access' AND 'Tools') 问题类型的 SiteType,即;从上面的例子中

如果输入是

  let selections=['Access','Tools']

预期输出是

{

  "SiteType": "Indoor",
  "ID": "420", 
  "Name": "Olympics"     
}

因为 LS_ID="420" 有两种问题类型。

我试图在 locationData 上迭代选定的值以获取 LS_ID 比较,但是,我得到了所有具有选定值的 LS-ID ('OR' 条件) 而不是获取具有所有选定值的 LS_ID **('AND' 条件)**

export function filterWithIssueSelectedValue(mainData,selections,locationData){
  let siteIds=[], filteredSSData=[]
  locationData.map((row,index)=>{
    selections.map((issue)=>{
      if(_.includes(row["Problem Type"], issue)){
        siteIds.push(row.LS_ID)
     }
  })     
})

 siteIds=_.uniq(siteIds);
 if(siteIds && siteIds.length){
    mainData.map((row,index)=>{
        siteIds.map((id)=>{
                if(row.ID==id){
                    filteredSSData.push(row)
                }
        })
    })
}

filteredSSData=_.uniqBy(filteredSSData, 'ID')
return filteredSSData
}

有人可以帮我过滤一下吗。谢谢提前!!

【问题讨论】:

    标签: javascript jquery arrays filter


    【解决方案1】:

    应该这样做:

    let locationData= [
      {
        "Name": "Olympics",
        "Problem Type": "Access",
        "LS_ID": "421"
      },
      {
        "Name": "Olympics",
        "Problem Type": "Route Issue",
        "LS_ID": "420"
      },
      {
        "Name": "Olympics",
        "Problem Type": "Tools",
        "LS_ID": "420"
      },
      {
        "Name": "Olympics",
        "Problem Type": "Access",
        "LS_ID": "420"
      },
      {
        "Name": "Olympics",
        "Problem Type": "Tools",
        "LS_ID": "422"
      }
    ]
    
    let mainData= [
      {
        "SiteType": "Outdoor",
        "ID": "421", 
        "Name": "Olympics"     
      },
      {
        "SiteType": "Indoor",
        "ID": "420", 
        "Name": "Olympics"     
      },
      {
        "SiteType": "International",
        "ID": "422", 
        "Name": "Olympics"    
      },
      {
        "SiteType": "Local",
        "ID": "423",  
        "Name": "Olympics"    
      }
    ]
    
    const findSiteThatHasProblems = (problems = []) =>
      mainData.filter(location =>
        problems.every(problem => 
          !!locationData.find(locationInfo =>
            locationInfo.LS_ID === location.ID && locationInfo['Problem Type'] === problem
          )
        )
      )
    
    console.log(findSiteThatHasProblems(['Tools', 'Access']))

    如果您希望我为任何代码添加解释,请告诉我!

    【讨论】:

    • 您可以使用.every().some(),而不是依赖于对对象和数组使用逻辑运算符。如果您看不到array.filter( !array.map(... !!array.find(...))) 不需要解释,我想知道什么值得解释..大声笑
    • 是的,有一些非常简洁的语法可能会造成混淆。我的意思是我不确定 OP 是否希望我特别解释任何事情,如果 OP 不需要它,我不想写一个很长的解释。 .every 是个好主意,我已经编辑了。
    • 我认为更改为.every() 消除了很多的歧义。我认为它需要更多,但现在它实际上看起来很简单。感谢您更新。
    【解决方案2】:

    我建议先过滤 id 并将结果用于过滤mainData

    var locationData = [{ Name: "Olympics", "Problem Type": "Access", LS_ID: "421" }, { Name: "Olympics", "Problem Type": "Route Issue", LS_ID: "420" }, { Name: "Olympics", "Problem Type": "Tools", LS_ID: "420" }, { Name: "Olympics", "Problem Type": "Access", LS_ID: "420" }, { Name: "Olympics", "Problem Type": "Tools", LS_ID: "422" }],
        mainData = [{ SiteType: "Outdoor", ID: "421", Name: "Olympics" }, { SiteType: "Indoor", ID: "420", Name: "Olympics" }, { SiteType: "International", ID: "422", Name: "Olympics" }, { SiteType: "Local", ID: "423", Name: "Olympics" }],
        selections = ['Access', 'Tools'],
        ids = Array.from(
            locationData
                .filter(({ 'Problem Type': type }) => selections.includes(type))
                .reduce((m, { LS_ID }) => m.set(LS_ID, (m.get(LS_ID) || 0) + 1), new Map)
                .entries()
            )
            .filter(({ 1: count }) => count === selections.length)
            .map(({ 0: id }) => id),
        result = mainData.filter(({ ID }) => ids.includes(ID));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      猜你喜欢
      • 2019-04-04
      • 2021-06-06
      • 2020-12-16
      • 1970-01-01
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-18
      相关资源
      最近更新 更多