Javascript嵌套对象过滤创建新对象

时间:2018-04-20 01:26:20

标签: javascript json filter javascript-objects

假设我有对象

let x = { "people" :{
             "Sally": "value",
             "Bob" : "other value"
                    },
          "cars" :{
             "Saab" : "this",
             "Chevy": "that"
                    },
           "trees":{
              "Birch" : "what",
              "Oak" : "where"
                    }
                }

我想搜索,所以如果我搜索“S”,我会找回一个

的数组
{ "people" :{
     "Sally": "value",
          },
  "cars" :{
     "Saab" : "this",
          }
}

如果我搜索“b”,我会得到:

{ "people" :{
        "Bob" : "other value"
           },
   "trees":{
        "Birch" : "what",
           }
}

或“bo”将返回

    { "people" :{
        "Bob" : "other value"
     }

如果我搜索“e”,我会得到

{  "cars" :{
             "Chevy": "that"
            }
}

请注意,搜索“e”时未捕获“人物”和“树木”。

strut将具有固定的深度,我们只想捕获与过滤器匹配且没有子项的(我们对匹配的值也不感兴趣,只是键)。

添加npm依赖项是可以接受的。

尝试解决方案:

    filteredList(unfiltered,searchVal) {
  return unfiltered.filter(search=> {
    return search.toLowerCase().includes(searchVal.toLowerCase())
  })
}

显然还有更多,但我不确定要继续前进的方向。

2 个答案:

答案 0 :(得分:4)

这是一项基本尝试。它似乎工作得很好,但我非常确定它可能会变得更好。但我不知道如何。



let x = {
  "people": {
    "Sally": "value",
    "Bob": "other value"
  },
  "cars": {
    "Saab": "this",
    "Chevy": "that"
  },
  "trees": {
    "Birch": "what",
    "Oak": "where"
  }
}

let search = "B";

let result = {};

for (let key in x) {
  let tmp = {};
  for (let subKey in x[key]) {
    if (subKey.includes(search)) { // Use startsWithif you want even substring that aren't at the beginning
      tmp[subKey] = x[key][subKey];
    }
    if (Object.keys(tmp).length > 0) {
      result[key] = Object.assign({}, tmp);
    }
  }
}

console.log(result)




如果你想要任意深度,你应该尝试某种递归,但这会更复杂。

答案 1 :(得分:1)

这是一个使用lodash库的解决方案。 Lodash有许多非常有用的对象操作方法,在这种情况下_.pickBy_.mapValues可用于过滤嵌套对象。

示例:



let x = {
  "people": {
    "Sally": "value",
    "Bob": "other value"
  },
  "cars": {
    "Saab": "this",
    "Chevy": "that"
  },
  "trees": {
    "Birch": "what",
    "Oak": "where"
  }
}

function search(query) {
    query = query.toLowerCase();
    const matched = _.mapValues(x, v => _.pickBy(v, (_, k) => k.toLowerCase().includes(query)));
    return _.pickBy(matched, v => Object.keys(v).length)
}

console.log(search("S"))
console.log(search("b"))
console.log(search("bo"))
console.log(search("e"))

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.5/lodash.min.js"></script>
&#13;
&#13;
&#13;