简体   繁体   English

JS过滤器中的数组

[英]JS filter array by array within

I have an array as following 我有如下数组

  [{
    "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"
      }
     ]
  }
  ],

And when the user select a certain menu it needs to be filtered through it, 当用户选择某个菜单时,需要对其进行过滤,

Each dish objects may have more than one menu_id, 每个餐具对象可能具有多个menu_id,

i attempted using array.filter but i am having trouble figuring out how to filter from the Dish array through the sub array within. 我尝试使用array.filter但是我在弄清楚如何从Dish array通过子数组进行过滤时遇到了麻烦。

the code i attempted ( filterBy = 4 ) 我尝试的代码( filterBy = 4

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

console.log(result) gives me an empty array. console.log(result)给了我一个空数组。

if filterBy is = 4 the expected output is 如果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"
      }
     ]
  }

And if it filterBy is 3 then both objects should be the output 如果filterBy为3,则两个对象都应该是输出

how about this 这个怎么样

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 expects the function passed to return a boolean. .filter期望传递的函数返回布尔值。 In your case, the function returns nothing (or undefined ) which is always falsy. 在您的情况下,该函数不返回任何内容(或undefined ),这总是错误的。

One option is to use .find in the nested filter, and return a boolean depending on whether the result is undefined . 一种选择是在嵌套过滤器中使用.find ,并根据结果是否为undefined返回一个布尔值。

Here's a snippet. 这是一个片段。

 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); 

You can use "filter" as below 您可以如下使用“过滤器”

 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)) 

You can also use grep function 您也可以使用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/ http://jsfiddle.net/ejPV4/

Your question a bit unclear of final goal, but if you want to filter top level objects, ie if top level object has to be present if and only if it has dish with menu_id === filterBy , then: 您的问题尚不清楚最终目标,但如果您要过滤顶级对象,即,当且仅当它具有menu_id === filterBy菜时,才必须存在顶级对象,则:

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

Above will only filter your rows if restaurant_dish_menus has items with menu_id === filterBy . 如果restaurant_dish_menus menu_id === filterBy项为menu_id === filterBy则以上内容仅过滤您的行。 But restaurant_dish_menus , of such objects remain unfiltered. 但是这类对象的restaurant_dish_menus仍未过滤。

Result: 结果:

[{
  "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
    }
  ]
}]

But if you want to filter top level and filter restaurant_dish_menus also, ie modify top level object, then: 但是,如果您要过滤顶级商品并同时过滤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)};
});

This will first filter the row objects which has menu_id === filterBy , and then also filter restaurant_dish_menus , to include only once menu_id === filterBy , effectively modifying the row object, ie map . 这将首先过滤具有menu_id === filterBy的行对象,然后再过滤restaurant_dish_menus ,使其仅包含一次menu_id === filterBy ,从而有效地修改行对象,即map

Result: 结果:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM