javascript多重过滤器或常规代码优化

时间:2019-03-26 09:12:44

标签: javascript performance lodash

我有一个像这样的对象数组:

const items = [
   {
       id: 1,
       status: "active",
       paid: true,
       name: "item-1"
   },
   {
       id: 2,
       status: "active",
       paid: false,
       name: "item-2"
   },
   {
       id: 3,
       status: "not active",
       paid: false,
       name: "item-3"
   },
]

我有一个函数可以像这样过滤它:

// arr is array of items
// status if null mean select all by status
// paid if null mean select all by paid
// status and paid if null mean select all by status and paid
function filterItem(arr, status, paid){
    const result = [];
    arr.forEach((item) => {
         if (status && paid) {
                if (status === item.status
                     && paid === item.paid.toString()) {
                     result.push(item);
                }
         } 
         else if(status){
                 if (status === item.status) {
                      result.push(item);
                 }
         }
         else if(paid){
                 if (paid == item.paid.toString()) {
                       result.push(item);
                 }
         }
         else result.push(item);
    })
    return result;
}

在此功能 filterItem 中:

状态是字符串,可以为空

付费是字符串,并且可以为空

预期输出:

状态和已付款为空 console.log(filterItem(items, null, null));

[
   {
       id: 1,
       status: "active",
       paid: true,
       name: "item-1"
   },
   {
       id: 2,
       status: "active",
       paid: false,
       name: "item-2"
   },
   {
       id: 3,
       status: "not active",
       paid: false,
       name: "item-3"
   },
]

如果支付的费用为空且状态为有效 console.log(filterItem(items, 'active', null))

[
   {
       id: 1,
       status: "active",
       paid: true,
       name: "item-1"
   },
   {
       id: 2,
       status: "active",
       paid: false,
       name: "item-2"
   }
]

等等

我相信使用es6或lodash的方法很短。我需要您的建议,请查看我的简单代码,还有比我更简单的代码吗?

4 个答案:

答案 0 :(得分:3)

您可以filter像这样:

const items=[{id:1,status:"active",paid:true,name:"item-1"},{id:2,status:"active",paid:false,name:"item-2"},{id:3,status:"not active",paid:false,name:"item-3"},]

function filterItem(arr, status, paid){
  return arr.filter(a =>
    (status === null || a.status === status) &&
    (paid === null || a.paid === paid)
  )
}

console.log(filterItem(items, "active", null))
console.log(filterItem(items, null, false))
console.log(filterItem(items, "active", true)) // both conditions
console.log(filterItem(items, null, null)) // returns everything

答案 1 :(得分:1)

您可以使用通用方法,首先使用所需的过滤器/属性/值构建一个数组,然后将Array#every与过滤器一起使用来过滤该数组。

如果需要,可以轻松扩展此方法以获取更多属性。

function filterItem(array, status, paid) {
    var filters = [];

    if (status !== null) filters.push(['status', status]);
    if (paid !== null) filters.push(['paid', paid]);

    return array.filter(item => filters.every(([k, v]) => item[k] === v));
}

const items = [{ id: 1, status: "active", paid: true, name: "item-1" }, { id: 2, status: "active", paid: false, name: "item-2" }, { id: 3, status: "not active", paid: false, name: "item-3" }];

console.log(filterItem(items, "active", true));

答案 2 :(得分:0)

您可以传递所需过滤条件的对象引用,并使用.every()来检查赋予函数的所有条件是否与数组中的项目匹配。这样,您就不仅限于statuspaid属性,还可以检查对象数组中可能存在的任何属性。

const items = [
   {
       id: 1,
       status: "active",
       paid: true,
       name: "item-1"
   },
   {
       id: 2,
       status: "active",
       paid: false,
       name: "item-2"
   },
   {
       id: 3,
       status: "not active",
       paid: false,
       name: "item-3"
   },
]

const filter = (array, criteria) => {
  const criteriaKeys = Object.keys(criteria)
  
  return array.filter(item => criteriaKeys.every(k => item[k] === criteria[k]))
}

console.log(filter(items, { status: 'active', paid: true }))
console.log(filter(items, { status: 'not active', paid: false }))
console.log(filter(items, { status: 'not active', paid: true }))
console.log(filter(items, { status: 'active' }))

答案 3 :(得分:0)

这应该更有效并且仍然可读:

const items = [
	   {
	       id: 1,
	       status: "active",
	       paid: true,
	       name: "item-1"
	   },
	   {
	       id: 2,
	       status: "active",
	       paid: false,
	       name: "item-2"
	   },
	   {
	       id: 3,
	       status: "not active",
	       paid: false,
	       name: "item-3"
	   },
	];

	let filterFunction = (ar, paid, status)=>{
		return ar.filter(item=>{
			let res = true;
			if(paid){
				res = item.paid === paid;
			}
			if(status){
				res = item.status === status;
			}
			return res;
		});
	};

	console.log(filterFunction(items, null, "active"));