JS过滤数组内的数组

JS filter array by array within

我有一个数组如下

  [{
    "id": 68,
    "proffesional_photo": "",
    "top_image": "https://sampleimage.jpg",
    "ratings": "1",
    "price": 690,
    "description": null,
    "type": true,
    "promo": 0,
    "status": true,
    "item": {
      "Item_name": "Dark Chocolate Latte"
    },
    "restaurant_dish_menus": [
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 4,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      },
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 3,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      }
     ]
  },
  {
    "id": 69,
    "proffesional_photo": "",
    "top_image": "https://sampleimage2.jpg",
    "ratings": "1",
    "price": 700,
    "description": null,
    "type": true,
    "promo": 0,
    "status": true,
    "item": {
      "Item_name": "Latte"
    },
    "restaurant_dish_menus": [
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 3,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      }
     ]
  }
  ],

而当用户select某个菜单需要通过它进行过滤时,

每个菜品对象可能不止一个menu_id,

我尝试使用 array.filter,但我无法弄清楚如何通过子数组从 Dish array 中进行过滤。

我尝试的代码 (filterBy = 4)

let result = data.filter(function(row) {
  row.restaurant_dish_menus.filter(function(i) {
    return i.menu_id == filterBy;
  });
});

console.log(result) 给我一个空数组。

如果filterBy is = 4预期输出是

{
    "id": 68,
    "proffesional_photo": "",
    "top_image": "https://sampleimage.jpg",
    "ratings": "1",
    "price": 690,
    "description": null,
    "type": true,
    "promo": 0,
    "status": true,
    "item": {
      "Item_name": "Dark Chocolate Latte"
    },
    "restaurant_dish_menus": [
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 4,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      },
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 3,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      }
     ]
  }

如果 filterBy 是 3 那么两个对象都应该是输出

你也可以使用grep函数

var menus=  {
    "id": 68,
    "proffesional_photo": "",
    "top_image": "https://sampleimage.jpg",
    "ratings": "1",
    "price": 690,
    "description": null,
    "type": true,
    "promo": 0,
    "status": true,
    "item": {
      "Item_name": "Dark Chocolate Latte"
    },
    "restaurant_dish_menus": [
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 4,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      },
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 3,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      }
     ]
  };

var found_names = $.grep(menus.restaurant_dish_menus, function(v) {
    return v.menu_id ===4;
});

console.log(found_names);

http://jsfiddle.net/ejPV4/

.filter 期望传递给 return 的函数是一个布尔值。在您的情况下,函数 return 什么都没有(或 undefined),它始终是假的。

一个选项是在嵌套过滤器中使用 .find,return 布尔值取决于结果是否为 undefined

这是一个片段。

let data = [{
  "id": 68,
  "proffesional_photo": "",
  "top_image": "https://sampleimage.jpg",
  "ratings": "1",
  "price": 690,
  "description": null,
  "type": true,
  "promo": 0,
  "status": true,
  "item": {
    "Item_name": "Dark Chocolate Latte"
  },
  "restaurant_dish_menus": [{
      "id": 1,
      "res_dish_id": 1318,
      "menu_id": 4,
      "createdAt": "2018-11-13T04:28:17.000Z",
      "updatedAt": "2018-11-13T04:28:17.000Z"
    },
    {
      "id": 1,
      "res_dish_id": 1318,
      "menu_id": 3,
      "createdAt": "2018-11-13T04:28:17.000Z",
      "updatedAt": "2018-11-13T04:28:17.000Z"
    }
  ]
}, {
  "id": 69,
  "proffesional_photo": "",
  "top_image": "https://sampleimage.jpg",
  "ratings": "1",
  "price": 690,
  "description": null,
  "type": true,
  "promo": 0,
  "status": true,
  "item": {
    "Item_name": "Dark Chocolate Latte"
  },
  "restaurant_dish_menus": [{
      "id": 1,
      "res_dish_id": 1318,
      "menu_id": 6,
      "createdAt": "2018-11-13T04:28:17.000Z",
      "updatedAt": "2018-11-13T04:28:17.000Z"
    },
    {
      "id": 1,
      "res_dish_id": 1318,
      "menu_id": 5,
      "createdAt": "2018-11-13T04:28:17.000Z",
      "updatedAt": "2018-11-13T04:28:17.000Z"
    }
  ]
}, ]

let filterBy = 4;

let result = data.filter(function(row) {
  return row.restaurant_dish_menus.find(function(i) {
    return i.menu_id == filterBy;
  }) !== undefined;
});

console.log(result);

你的问题对最终目标有点不清楚,但如果你想过滤顶级对象,即如果顶级对象必须存在当且仅当它有带 menu_id === filterBy 的盘子时,那么:

let result = data.filter(row => {
  return row.restaurant_dish_menus.some(({menu_id}) => menu_id === filterBy);
});

如果 restaurant_dish_menus 包含带有 menu_id === filterBy 的项目,以上将仅过滤您的行。但是 restaurant_dish_menus,这样的对象仍未过滤。

结果:

[{
  "id": 68,
  // skipped
  "item": {
    "Item_name": "Dark Chocolate Latte"
  },
  "restaurant_dish_menus": [
    {
      "id": 1,
      "res_dish_id": 1318,
      "menu_id": 4,
      // skipped
    },
    {
      "id": 1,
      "res_dish_id": 1318,
      "menu_id": 3,
      // skipped
    }
  ]
}]

但是如果你想过滤顶级并过滤restaurant_dish_menus,即修改顶级对象,那么:

let result = data.filter(row => {
  return row.restaurant_dish_menus.some(({menu_id}) => menu_id === filterBy);
}).map(row => {
  return {...row, restaurant_dish_menus: row.restaurant_dish_menus.filter(i => i.menu_id === filterBy)};
});

这将首先过滤具有menu_id === filterBy的行对象,然后还过滤restaurant_dish_menus,只包含一次menu_id === filterBy,有效地修改行对象,即map.

结果:

[{
  "id": 68,
  // skipped
  "item": {
    "Item_name": "Dark Chocolate Latte"
  },
  "restaurant_dish_menus": [
    {
      "id": 1,
      "res_dish_id": 1318,
      "menu_id": 4,
      // skipped
    }
  ]
}]

这个怎么样

var data =   [{
    "id": 68,
    "proffesional_photo": "",
    "top_image": "https://sampleimage.jpg",
    "ratings": "1",
    "price": 690,
    "description": null,
    "type": true,
    "promo": 0,
    "status": true,
    "item": {
      "Item_name": "Dark Chocolate Latte"
    },
    "restaurant_dish_menus": [
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 4,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      },
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 3,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      }
     ]
  }];

  var result = data.filter(function(m) {
    return m.restaurant_dish_menus.some(function(d) {
      return d.menu_id === 4;
    });
  })

您可以使用"filter"如下

var data = [{
    "id": 68,
    "proffesional_photo": "",
    "top_image": "https://sampleimage.jpg",
    "ratings": "1",
    "price": 690,
    "description": null,
    "type": true,
    "promo": 0,
    "status": true,
    "item": {
      "Item_name": "Dark Chocolate Latte"
    },
    "restaurant_dish_menus": [
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 4,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      },
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 3,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      }
     ]
  },
  {
    "id": 69,
    "proffesional_photo": "",
    "top_image": "https://sampleimage2.jpg",
    "ratings": "1",
    "price": 700,
    "description": null,
    "type": true,
    "promo": 0,
    "status": true,
    "item": {
      "Item_name": "Latte"
    },
    "restaurant_dish_menus": [
      {
        "id": 1,
        "res_dish_id": 1318,
        "menu_id": 3,
        "createdAt": "2018-11-13T04:28:17.000Z",
        "updatedAt": "2018-11-13T04:28:17.000Z"
      }
     ]
  }
  ]

function filterBy(f) {
    return data.filter(d => d.restaurant_dish_menus.some(({ menu_id }) => menu_id == f))
}

console.log(filterBy(4))

console.log(filterBy(3))