Javascript how to filter arrays matching a keyword

倖福魔咒の 提交于 2019-12-24 05:05:10

问题


I have a deeply nested array as follows:

{[{
    id: "1",
    experts: [
        {instruments: [{guitar: ["John", "Maria"], 
                         piano: ["Hans", "Sarah", "Nancy"] }],
         name: "Columbia Records", published: "1930"
        },
        {instruments: [{guitar: ["Pablo"], 
                        drums: ["Jeb", "Xiao"]} ],
         name: "Atlas Records", published: "1978"
        }
    ]
]},
{
    id: "2",
    experts: [
        {instruments: [{sitar: ["Anaka", "Reha"], 
                        chello: ["Hans", "Raphael", "Stuart"]} ],
         name: "Touchstone Records", published: "1991"
        },
        {instruments: [{viola: ["Richard", "Farah"], 
                        buss: ["Tina", "Max"]} ],
         name: "Atlas Records", published: "1978"
        }
    ]

}

I need to perform leveled search. For example if my search key is "Jo" the result should be:

[{
        id: "1",
        experts: [{"instruments": [
                                   "guitar": ["John"]
                                  ]              
                 ],
             "name": "Columbia Records", "published": "1930"
 }]

In other words each nested level, I just filter based on the key and if it does not exist then remove the nested object and go further. If the search key is "1" it will return the whole first object.

I am looking into loadsh and its filter function which takes a predicate but not sure how to achieve the search arbitrary nesting.


回答1:


It looked like fun so here. To begin with your object declaration had lots of errors. You were missing closing tags, and you don't create arrays with keys like ["key":"value"], that's for objects {"key":"value"}

var testArray = [{
    id: "1",
    experts: [
        {"instruments": {"guitar": ["John", "Maria"], 
                         "piano": ["Hans", "Sarah", "Nancy"] },
         "name": "Columbia Records", "published": "1930"
        },
        {"instruments": {"guitar": ["Pablo"], 
                         "drums": ["Jeb", "Xiao"] },
         "name": "Atlas Records", "published": "1978"
        }
    ]
},
{
    id: "2",
    experts: [
        {"instruments": {"sitar": ["Anaka", "Reha"], 
                         "chello": ["Hans", "Raphael", "Stuart"] },
         "name": "Touchstone Records", "published": "1991"
        },
        {"instruments": {"viola": ["Richard", "Farah"], 
                         "buss": ["Tina", "Max"] },
         "name": "Atlas Records", "published": "1978"
        }
    ]
}];

One way is to use recursion, something as such:

function deepSearchForValue(obj, searchstring) {
  var doesValueExist = function(item) {
    if (typeof item === "string") {
      return item.toLowerCase().indexOf(searchstring.toLowerCase()) >= 0;
    } else {
      return doesValueExistRecursive(item);
    }
  }

  var doesValueExistRecursive = function(item) {
     for (i in item) { 
        if (doesValueExist(item[i])) {
           return true;
        }
     }
     return false;
  }

  return obj.filter(doesValueExistRecursive);
}

And you would call it like so

var matchedItems = deepSearchForValue(testArray, "reh");

console.log("found:");
console.log(matchedItems);



回答2:


you'd probably want something like this. May be a few modification in the algo gives you what you exactly are after:

var arr = [
  {
    id: "1",
    experts: [
      {
        "instruments": {
          "guitar": ["John", "Maria"], 
          "piano": ["Hans", "Sarah", "Nancy"] 
        },
        "name": "Columbia Records", 
        "published": "1930"
      },
      {
        "instruments": {
          "guitar": ["Pablo"], 
          "drums": ["Jeb", "Xiao"]
        },
        "name": "Atlas Records", 
        "published": "1978"
      }
    ]
},
{
    id: "2",
    experts: [
        {
          "instruments": {
            "sitar": ["Anaka", "Reha"],
            "chello": ["Hans", "Raphael", "Stuart"]
          },
         "name": "Touchstone Records", 
         "published": "1991"
        },
        {
          "instruments": {
            "viola": ["Richard", "Farah"],
            "buss": ["Tina", "Max"]
          },
         "name": "Atlas Records", 
         "published": "1978"
        }
    ]
}];

var t = _.remove(arr, function(n) {
  if(!_.includes(n, 'Jo')){
    return n;
  }
});

document.getElementById('search').innerHTML = JSON.stringify(t);
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.rawgit.com/lodash/lodash/3.0.1/lodash.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div id="search"></div>
</body>
</html>


来源:https://stackoverflow.com/questions/31215369/javascript-how-to-filter-arrays-matching-a-keyword

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!