简体   繁体   中英

Javascript filter array of objects by key of another array of objects

I have an array of products and an array of products that a user has access to. They share a common ID. I want to filter the array of products to only return those that the user has access to.

All products ( products )

[{
  "productName": "My Product"
   "p_id": "1"
},...
]

My available products ( myProducts )

[
  {
    "i_items": "[{\"act\":\"new\",\"app\":\"nexus\",\"type\":\"package\",\"cost\":\"0.00\",\"tax\":null,\"quantity\":1,\"itemName\":\"My Product\",\"itemID\":1,\"physical\":false,\"methods\":\"*\",\"cfields\":[],\"extra\":null,\"renew_term\":1,\"renew_units\":\"m\",\"renew_cost\":\"100.00\",\"grace_period\":86400}]"
  },...
]

Edit:

The below solution is returning []

// Extract available IDs into a Set:
const availableIds = new Set(this.myProducts.flatMap(({i_items}) => 
    JSON.parse(i_items).map(item => ""+item.itemID))
);
console.log(availableIds); //Set(1) {"3"}
// Use the Set to filter the products:
console.log(availableIds.has("3")); //true
const filtered = this.products.filter(({p_id}) => availableIds.has(p_id));
console.log(filtered); // []

Final edit: thanks to everyone who helped. This last issue was caused by not casting the id to string. Once I changed availableIds.has(p_id) -> availableIds.has(""+p_id) it worked.

You can use map and JSON.parse to extract the itemID values from the second data set, and turn those into a Set . Then apply a filter on the product data using that set:

 // Sample data const allProducts = [{"productName": "My Product","p_id": "1"},{"productName": "My unused Product","p_id": "4"},{"productName": "My Other Product","p_id": "5"},{"productName": "My unused Product 2","p_id": "6"},{"productName": "My luxury Product","p_id": "9"},{"productName": "My lucky Product","p_id": "13"}]; const available = [{"i_items": "[{\\"itemID\\":1},{\\"itemID\\":13}]"},{"i_items": "[{\\"itemID\\":5},{\\"itemID\\":9}]"}]; // Extract available IDs into a Set: const availableIds = new Set(available.flatMap(({i_items}) => JSON.parse(i_items).map(item => ""+item.itemID)) ); // Use the Set to filter the products: const filtered = allProducts.filter(({p_id}) => availableIds.has(p_id)); console.log(filtered); 

As others have said, this is a case of parsing the available items, and then checking to see if the relevant id is present:

 const a = [ { "productName": "My Product", "p_id": "1" }, { "productName": "My Other Product", "p_id": "2" } ] const availableItems = [ { "i_items": "[{\\"act\\":\\"new\\",\\"app\\":\\"nexus\\",\\"type\\":\\"package\\",\\"cost\\":\\"0.00\\",\\"tax\\":null,\\"quantity\\":1,\\"itemName\\":\\"My Product\\",\\"itemID\\":1,\\"physical\\":false,\\"methods\\":\\"*\\",\\"cfields\\":[],\\"extra\\":null,\\"renew_term\\":1,\\"renew_units\\":\\"m\\",\\"renew_cost\\":\\"100.00\\",\\"grace_period\\":86400}]" }, ]; const path = k => x => x[k]; const parseAvailable = item => JSON.parse(item['i_items']); const stringify = x => `${x}`; const getItemIdAsString = x => stringify(path('itemID')(x)) const availabilityChecker = available => product => parseAvailable(available) .map(getItemIdAsString) .indexOf(product['p_id']) > -1; const isProductAvailable = availabilityChecker(availableItems[0]); const result = isProductAvailable(a[0]) const resultTwo = isProductAvailable(a[1]) console.dir(result) console.dir(resultTwo) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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