根据数组输入过滤对象数组

时间:2019-09-23 06:53:15

标签: javascript filter

我有Array的{​​{1}}。

每个对象数组包含一个数组Objects,并且该数组中的每个项目都是一个包含数组items的对象:

category

为了使情况更清楚,将通过以下方式执行对var obj = [ // first object { label: 'Label 1', // first items items: [ { id: 1, itemName: 'Item Name 1', img: 'imgs/path-to1.jpeg', sizes: [], colors: [], // first category category: [ 'I', 'E', 'M' ], defaultChoices: {} }, { id: 2, itemName: 'Item Name 2', img: 'imgs/path-to2.jpeg', sizes: [], colors: [], // second category category: [ 'I', 'E' ], defaultChoices: {} }, { id: 3, itemName: 'Item Name 3', img: 'imgs/path-to3.jpeg', sizes: [], colors: [], // third category category: [ 'I' ], defaultChoices: {} }, ] }, // second object { label: 'Label 2', // second items items: [ { id: 7, itemName: 'Item Name 7', img: 'imgs/path-to7.jpeg', sizes: [], colors: [], // fourth category category: [ 'I', 'M' ], defaultChoices: {} }, ... 的典型直接访问:category

从应用程序的前端,用户可以根据自己的选择将以下数组之一发送到应用程序:

  • obj[0].items[0].category;
  • ['I'];
  • ['E'];
  • ['M'];
  • ['I','E'];
  • ['I','M'];
  • ['E','M'];
  • ...;

然后,应用程序应返回已过滤的obj数组:例如,如果用户发送了['I','E','M'],则该数组应包含category包含“ I”的所有对象。如果用户发送了['I'],则该数组应包含category包含['E','M']的任何对象(无论category是否为['E','M']),等等。

我写了很多关于JS ['E','M','I']函数的文档,但是我无法开发一个函数,该函数在给定用户数组的情况下可以通过过滤filter返回一个新数组。我找到了许多带有非现实示例的文档,例如:

obj

[UPDATE]我添加了一个更实际的数据示例,抱歉,以前没有提供它:https://drive.google.com/open?id=1sdRx6sQ-cnRXJ8YCe4QH2Sy5fa5mopYW

4 个答案:

答案 0 :(得分:3)

如果您要按类别过滤,数组中object的数目保持不变(即使该对象中的所有项目都被过滤掉,并且该对象中没有项目),则应该你想要什么:

var obj = [ // I removed some unnecessary params to make it clear, which shouldn't affect any
  {
    label: 'Label 1',
    items: [
      {
        id: 1,
        category: ['I', 'E', 'M'],
      },
      {
        id: 2,
        category: ['I', 'E'],
      },
      {
        id: 3,
        category: ['I'],
      },
    ]
  },
  {
    label: 'Label 2',
    items: [
      {
        id: 7,
        category: ['I', 'M'],
      },
    ]}
]


function filterByCategory(obj, categories) {
  return obj.map( o => ({
    ...o, // copy everything(i.e. label, items)
    items: o.items.filter(item => // modify items in the obj
       categories.some(c => item.category && item.category.includes(c)) // keep item if some categories are in item
    )
  }))
}
const filteredObj = filterByCategory(obj, ['I', 'E'])
console.log(filteredObj)

如果要进一步过滤掉没有项目的对象,可以添加 .filter(o => o.items.length)末尾的filterByCategory

实时示例:

var data = [ { label: 'Label 1', items: [{ id: 1, itemName: 'Item Name 1', img: 'imgs/path-to1.jpeg', sizes: [], colors: [], category: [ 'I', 'E', 'M' ], defaultChoices: {} }, { id: 2, itemName: 'Item Name 2', img: 'imgs/path-to2.jpeg', sizes: [], colors: [], category: [ 'I', 'E' ], defaultChoices: {} }, { id: 3, itemName: 'Item Name 3', img: 'imgs/path-to3.jpeg', sizes: [], colors: [], category: [ 'I' ], defaultChoices: {} }, ] }, { label: 'Label 2', items: [{ id: 7, itemName: 'Item Name 7', img: 'imgs/path-to7.jpeg', sizes: [], colors: [], category: [ 'I', 'M' ], defaultChoices: {} }] } ]; 

function filterByCategory(data, category) {
  return data.map(obj => {
    return { ...obj,
      "items": obj.items.filter(item =>
        category.some(value => item.category && item.category.includes(value))
      )
    };
  });
}

console.log(filterByCategory(data, ['E', 'M']));

答案 1 :(得分:2)

此代码遍历所有对象和项目,并仅使用具有指定类别的项目创建一个新的对象。注释中有对《守则》的更详细描述:

// function where you enter the Objects and the Categories you want to filter
function getFilterObjectItems(objs, categories){
  // Filtered Objects
  return objs.map(function(obj) {
    // Creates a new Item
    var newObject = {label: obj.label, items:[]};
    //iterate through all items in an Object looking for items with matching Category
    obj.items.forEach(function(item){
      // if one category entry matches add item to new Object
      //  the "some" function returns "true" or "false" if one item matches the critieria
      if(item && item.category && item.category.some && item.category.some(cat => searchedCAT.indexOf(cat)>-1)){
        // the original item will be added to the new item ist
        newObject.items.push(item);
      }
    });
    return newObject;
  })
  // filters all New Objects that don't have items
  .filter(newObject => newObject.items.length>0);
}


// DATA from the Question
var obj = [
  // first object
  {
    label: 'Label 1',
    // first items
    items: [
      {
        id: 1,
        itemName: 'Item Name 1',
        img: 'imgs/path-to1.jpeg',
        sizes: [],
        colors: [],
        // first category
        category: [
          'I',
          'E',
          'M'
        ],
        defaultChoices: {}
      },
      {
        id: 2,
        itemName: 'Item Name 2',
        img: 'imgs/path-to2.jpeg',
        sizes: [],
        colors: [],
        // second category
        category: [
          'I',
          'E'
        ],
        defaultChoices: {}
      },
      {
        id: 3,
        itemName: 'Item Name 3',
        img: 'imgs/path-to3.jpeg',
        sizes: [],
        colors: [],
        // third category
        category: [
          'I'
        ],
        defaultChoices: {}
      },
    ]
  },]

// search Categories
var searchedCAT = ['I'];


// Calling the Function
console.info(getFilterObjectItems(obj, searchedCAT));

答案 2 :(得分:1)

const UserChoice = ['E', 'X'];
const filtered = obj.filter(o => {
  const filteredItems = o.items.filter(item =>
    item.category.map(c => UserChoice.includes(c)).includes(true)
  );
  if (filteredItems.length > 0) {
    o.items = filteredItems;
    return o;
  }
});

“已过滤”将具有您已过滤的obj

答案 3 :(得分:1)

此解决方案使用四种Array方法来过滤obj数组:.filter.some.every.includes

// __Simplified version of the 'obj' array__
var obj = [
  {
    label: '1',
    items: [
      {id:1, category:['I','E','M']},
      {id:2, category:['I','E'] },
      {id:3, category:['I']}
    ]
  },
  {
    label: '2',
    items: [
      { id:7, category: ['I','M']}
    ]
  }
];


// __The filter function__
// (Takes an array of user input, and filters the global
//   `obj` array to return a new array)
function filterObj(inputArray){ 
  const filtered = obj.filter( object => // Keep the object if...
    object.items.some( item => // some item in the object passes this test:
      inputArray.every( value => // For every value in the input array...
        item.category.includes(value) // the item's 'category' array includes value
      )
    )
  );
  return filtered;
}

// __Testing function__
// (Calls `filterObj` on a test array and logs the results)
function test(input){
  console.log(`Testing this input: ${ input }`);
  console.log("Obects having `some` item where `every` value in the input array is `included`:");
  filterObj(input).forEach( matchingObject => { console.log(matchingObject.label); });
  console.log("");
}

// __Tests__
test(['I','M']);
test(['I','E']);

(注意:输出根据OP的原始规范,即 “例如,如果用户发送了['I'],则数组应该包含其中类别包含'I'的所有对象”)