【问题标题】:Vue/Javascript filter in deep object inside object array对象数组内的深层对象中的 Vue/Javascript 过滤器
【发布时间】:2020-08-28 04:02:33
【问题描述】:

我需要在具有多个对象的数组中深入过滤数组内的类别对象。在 API 调用中,我将拥有这个具有嵌套类别的对象数组。如果每个对象包含特定的类别 ID,我需要过滤它。这是 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",
        },
      ],
    },
  },
]

我想用只包含 "parent" : 15 的对象创建一个新数组,但是如何深入过滤这 3 个对象?我试过了,但它不起作用

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
}

【问题讨论】:

  • condition ? val1 : val2 : val3 语法无效。

标签: javascript


【解决方案1】:

您的意思是这样的 - 过滤位于主数组中的对象内部的数组?您可以根据需要迭代对象数组并循环过滤。或使用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)

或者,如果你的意思是你想过滤你的主数组,只包含具有某些值的嵌套数组的对象 - 那么这是对以前代码的一点修改

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)

【讨论】:

    【解决方案2】:

    下面的代码应返回一个仅包含 item 对象的数组,其中嵌套的 categories 数组已过滤匹配。

    注意:

    • 仅返回包含至少 1 个匹配类别的项目(这意味着如果项目不包含任何匹配类别,则它不会出现在输出中)。
    • 输出中仅显示匹配的类别。
    • 如果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);

    【讨论】:

    • 谢谢你,它可以工作,但在 Api 调用中我有很多对象。我更喜欢使用下面的地图方法。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    相关资源
    最近更新 更多