使用list- Javascript过滤对象列表

时间:2014-06-24 00:14:35

标签: javascript arrays object underscore.js javascript-objects

过滤包含带有列表的对象的列表最有效。我一直在寻找下划线的_.filter函数,但这需要数组并返回数组。

我想拍摄一个物体并按某个词过滤它。

例如,我将如何过滤:

    [
{level: "Title 1", details: [
    {real: "There we go", fake: "THERE_WE_GO"},
    {real: "Where is it", fake: "WHERE_IS_IT"},
    {real: "The dog jumped", fake: "THE_DOG_JUMPED"},
] }, 
{level: "Title 2", details: [
    {real: "There it is", fake: "THERE_IT_IS"},
    {real: "Car is flying", fake: "CAR_IS_FLYING"},
    {real: "Driving is fun", fake: "DRIVING_IS_FUN"}
] }, 
{level: "Title 2", details: [
    {real: "There he is", fake: "THERE_WE_GO"},
    {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"},
    {real: "The dog died", fake: "THE_DOG_DIED"},
    {real: "I am tired", fake: "I_AM_TIRED"},

]}
];

单词“the”

这样它返回

    [
{level: "Title 1", details: [
    {real: "There we go", fake: "THERE_WE_GO"},
    {real: "The dog jumped", fake: "THE_DOG_JUMPED"},
] }, 
{level: "Title 2", details: [
    {real: "There it is", fake: "THERE_IT_IS"},
] }, 
{level: "Title 2", details: [
    {real: "There he is", fake: "THERE_WE_GO"},
    {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"},
    {real: "The dog died", fake: "THE_DOG_DIED"},
]}
];

请注意,当用“the”这个词过滤时,我也想保留任何带有“the”字样的东西,例如“There”......我只去检查“是”这个词“位于细节数组内对象的”真实“索引中。

3 个答案:

答案 0 :(得分:0)

您可以使用filter,但是您必须在每个内部列表上应用一次,在外部列表上应用一次:

var phrase = "the".toUpperCase();
return _.filter(_.map(data, function(item) {
    return {
        level: item.level,
        details: _.filter(item.details, function(detail) {
            return detail.fake.indexOf(phrase) > -1;
        })
    };
}), function(item) {
    return item.details.length > 0;
});

从您的示例中我无法推断您是否需要外部filter,或者您是否不想删除带有空详细信息列表的项目。

答案 1 :(得分:0)

这是一个使用普通javascript的解决方案:

    var arr = [
    {level: "Title 1", details: [
        {real: "There we go", fake: "THERE_WE_GO"},
        {real: "Where is it", fake: "WHERE_IS_IT"},
        {real: "The dog jumped", fake: "THE_DOG_JUMPED"},
    ] },
    {level: "Title 2", details: [
        {real: "There it is", fake: "THERE_IT_IS"},
        {real: "Car is flying", fake: "CAR_IS_FLYING"},
        {real: "Driving is fun", fake: "DRIVING_IS_FUN"}
    ] },
    {level: "Title 3", details: [
        {real: "There he is", fake: "THERE_WE_GO"},
        {real: "Where is the dog", fake: "WHERE_IS_THE_DOG"},
        {real: "The dog died", fake: "THE_DOG_DIED"},
        {real: "I am tired", fake: "I_AM_TIRED"},

    ]}
];
function filterArr(arr, str) {
    var ret = new Array();
    for (var i = 0; arr[i]; i++) {
        var obj = arr[i].details;
        ret[i] = new Object();
        ret[i]['level'] = arr[i].level;
        ret[i]['details'] = [];

        for (var j = 0; obj[j]; j++) {
            if (obj[j].real.toLowerCase().indexOf(str.toLowerCase()) != -1) {

                ret[i].details.push(obj[j]);
            }


        }
    }
    return ret;
}
console.log( filterArr(arr, 'the'));

答案 2 :(得分:0)

这是另一个“普通”的JavaScript解决方案。它试图最小化硬编码属性,但可能并非真正必要。

您可以使用过滤器 forEach map 等在更少的代码中执行此操作,但通常普通循环比嵌套迭代器运行得更快:

  function filterOn(data, value) {
    var re = new RegExp(value,'i');
    var result = [];
    var details, keys, obj, temp;

    for (var i=0, iLen=data.length; i<iLen; i++) {
      temp = {level: data[i].level, details:[]};
      details = data[i].details;

      for (var j=0, jLen=details.length; j<jLen; j++) {
        obj = details[j];

        for (var p in obj) {

          if (obj.hasOwnProperty(p) && re.test(obj[p])) {
            temp.details.push(details[j]);
            break;
          }
        }
      }
      if (temp.details.length) result.push(temp);
    }
    return result;
  }