简体   繁体   English

对象数组内深层对象中的 Vue/Javascript 过滤器

[英]Vue/Javascript filter in deep object inside object array

I need to filter in deep the categories object inside an array, in an array with multiple objects.我需要在具有多个对象的数组中深入过滤数组内的类别对象。 In an API call , I will have this array of objects with nested categories.在 API 调用中,我将拥有具有嵌套类别的对象数组。 I need to filter each object if it contains specific category id.如果每个对象包含特定的类别 id,我需要过滤它。 This is the JSON -这是 JSON -

items_loop: [
  {
    ID: 1,
    name: "Item A",
    taxonomy: {
      categories: [
        {
          name: "Book",
          parent: 12,
          taxonomy: "category",
        },
        {
          name: "Cover",
          parent: 4,
          taxonomy: "category",
        },
        {
          name: "Other",
          parent: 15,
          taxonomy: "category",
        },
      ],
    },
  },
  {
    ID: 2,
    name: "Item B",
    taxonomy: {
      categories: [
        {
          name: "Toys",
          parent: 16,
          taxonomy: "category",
        },
        {
          name: "Book",
          parent: 12,
          taxonomy: "category",
        },
        {
          name: "Other",
          parent: 15,
          taxonomy: "category",
        },
      ],
    },
  },
  {
    ID: 3,
    name: "Item C",
    taxonomy: {
      categories: [
        {
          name: "Ext",
          parent: 6,
          taxonomy: "category",
        },
        {
          name: "Cover",
          parent: 4,
          taxonomy: "category",
        },
        {
          name: "Other",
          parent: 15,
          taxonomy: "category",
        },
      ],
    },
  },
]

I want to make a new array with object that contains only "parent" : 15 , but how I can filter in deep this 3 object ?我想用只包含“父”的对象创建一个新数组:15 ,但是我如何才能深入过滤这 3 个对象? I tried with this, but it's not working我试过这个,但它不起作用

function findInObjArray(array, value) {
  var found = []

  // Helper to search obj for value
  function findInObj(obj, value) {
    return Object.values(obj).some((v) =>
      // If v is an object, call recursively
      typeof v == "object" && v != "null"
        ? findInObj(v, value)
        : // If string, check if value is part of v
        typeof v == "string"
        ? v.indexOf(value) >= 0
        : // Check numbers, make NaN == NaN
        typeof v == "number"
        ? v === value || (isNaN(v) && isNaN(value))
        : // Otherwise look for strict equality: null, undefined, function, boolean
          v === value
    )
  }

  array.forEach(function (obj) {
    if (findInObj(obj, value)) found.push(obj)
  })

  return found
}

You mean something like this - filter arrays that is inside objects that is in your main array?您的意思是这样的 - 过滤主数组中对象内部的数组? You can iterate your array of object as you wish and do filter in cycle.您可以根据需要迭代对象数组并循环过滤。 Or use map method as in example below:或者使用map方法,如下例所示:

 const obj = [{ ID: 1, name: 'Item A', taxonomy : { categories : [{ name: "Book", parent: 12, taxonomy: "category", },{ name: "Cover", parent: 4, taxonomy: "category", },{ name: "Other", parent: 15, taxonomy: "category", }] } },{ ID: 2, name: 'Item B', taxonomy : { categories : [{ name: "Toys", parent: 16, taxonomy: "category", },{ name: "Book", parent: 12, taxonomy: "category", },{ name: "Other", parent: 15, taxonomy: "category", }] } },{ ID: 3, name: 'Item C', taxonomy : { categories : [{ name: "Ext", parent: 6, taxonomy: "category", },{ name: "Cover", parent: 4, taxonomy: "category", },{ name: "Other", parent: 15, taxonomy: "category", }] } }]; // Map and filter nested content const res = obj.map(a => { a.taxonomy.categories = a.taxonomy.categories.filter(x => x.parent === 15); return a; }); // Log console.log(res)

Or if you mean you want to filter your main array to only contain object that has nested array with some value - then this is little modification of previous code或者,如果您的意思是要过滤主数组以仅包含具有某些值的嵌套数组的对象 - 那么这是对先前代码的小修改

 const obj = [{ ID: 1, name: 'Item A', taxonomy : { categories : [{ name: "Book", parent: 12, taxonomy: "category", },{ name: "Cover", parent: 4, taxonomy: "category", },{ name: "Other", parent: 15, taxonomy: "category", }] } },{ ID: 2, name: 'Item B', taxonomy : { categories : [{ name: "Toys", parent: 16, taxonomy: "category", },{ name: "Book", parent: 12, taxonomy: "category", },{ name: "Other", parent: 15, taxonomy: "category", }] } },{ ID: 3, name: 'Item C', taxonomy : { categories : [{ name: "Ext", parent: 6, taxonomy: "category", },{ name: "Cover", parent: 4, taxonomy: "category", },{ name: "Other", parent: 15, taxonomy: "category", }] } }]; // Map and filter nested content const res = obj.filter(a => { if((a.taxonomy.categories.filter(x => x.parent === 6)).length > 0) return a; }); // Log console.log(res)

The code below should return an array of only item objects in which the nested categories array has been filtered for matches.下面的代码应该返回一个仅包含item对象的数组,其中嵌套的categories数组已被过滤以进行匹配。

Note that:注意:

  • Only items containing at least 1 matching category are returned (meaning if an item didn't contain any matching categories, it will not be present in the output).仅返回包含至少 1 个匹配类别的项目(意味着如果项目不包含任何匹配类别,则不会出现在输出中)。
  • Only matching categories are present in the output.输出中只存在匹配的类别。
  • If categoryFilterFunc returns no matches across all items and categories, the return value will be an empty array.如果categoryFilterFunc在所有项目和类别中都没有返回匹配项,则返回值将是一个空数组。

 const obj = { items_loop : [ { ID: 1, name: 'Item A', taxonomy : { categories : [ { name: "Book", parent: 12, taxonomy: "category", }, { name: "Cover", parent: 4, taxonomy: "category", }, { name: "Other", parent: 15, taxonomy: "category", }, ] } }, { ID: 2, name: 'Item B', taxonomy : { categories : [ { name: "Toys", parent: 16, taxonomy: "category", }, { name: "Book", parent: 12, taxonomy: "category", }, { name: "Other", parent: 15, taxonomy: "category", }, ] } }, { ID: 3, name: 'Item C', taxonomy : { categories : [ { name: "Ext", parent: 6, taxonomy: "category", }, { name: "Cover", parent: 4, taxonomy: "category", }, { name: "Other", parent: 15, taxonomy: "category", }, ] } }, ] }; function filterCategories(someObject, categoryFilterFunc) { return someObject.items_loop.reduce((accum, item) => { const filtered = item.taxonomy.categories.filter(categoryFilterFunc); if (filtered.length > 0) { // Creating a deep copy will have some performance impact (depending on // how many items and nested categories you need to iterate over) // but seems advisable for nested objects. Up to you if you // want to keep it. const deepCopy = JSON.parse(JSON.stringify(item)); deepCopy.taxonomy.categories = filtered; accum.push(deepCopy); } return accum; }, []); } const matchingItems = filterCategories(obj, categoryObj => 15 === categoryObj.parent); console.log(matchingItems);

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

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