根据条件过滤JavaScript数组

时间:2020-07-29 13:57:23

标签: javascript arrays filter

我正在生成一个动态数组,如下所示。我想要实现的是将第一个集合与第二个集合进行比较,并将基于id的通用项返回到一个新数组中。另外,待处理的值和必需的值应大于0。

例如,案例:1

let arr = [
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 0, pending: 0 }
  },
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 1, pending: 1 },
    2: { id: 3, name: "C", required: 0, pending: 0 }
  }
]

在这种情况下,结果将为A。

[
{ id: 1, name: "A", required: 1, pending: 1 }
]

另一种情况,案例:2 因为该数组是动态生成的。因此,以下是可能的。

let arr = [
      {
        0: { id: 1, name: "A", required: 1, pending: 1 },
        1: { id: 2, name: "B", required: 1, pending: 1 },
        2: { id: 3, name: "C", required: 0, pending: 0 }
      }
    ]

其预期输出为

  [
    { id: 1, name: "A", required: 1, pending: 1 },
    { id: 2, name: "B", required: 1, pending: 1 }
  ]

以下功能为情况1提供了所需的输出。此功能不适用于情况2。有人可以帮助我解决此问题吗?

let test = arr .reduce((p, c) => p.filter(e =>c.some(s => s.id === e.id && s.pending> 0 && e.pending> 0 && s.required> 0 && e.required> 0)));

4 个答案:

答案 0 :(得分:1)

您可以使用mapObject.values来获取嵌套对象的值和要进行重复数据删除的对象

var arr=[{
  0:{id: 1, name: "A", required: 1, pending: 1},
  1:{id: 2, name: "B", required: 0, pending: 0}
  },
  {
  0:{id: 1, name: "A", required: 1, pending: 1},
  1:{id: 2, name: "B", required: 1, pending: 1},
  2:{id: 3, name: "C", required: 0, pending: 0}
  }
  ]


  map1=new Map()
  map2=new Map()

  var res = arr.map(o => Object.values(o).forEach(
  s => { if(s.required > 0 && s.pending > 0 && !map2.get(s.name)) 
          map1.set(s.name,s)
         else map2.set(s.name,s)
  }))
  console.log([...map1.values()])

let arr = [
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 1, pending: 1 },
    2: { id: 3, name: "C", required: 0, pending: 0 }
  }
]


  map1=new Map()
  map2=new Map()

  var res = arr.map(o => Object.values(o).forEach(
  s => (s.required > 0 && s.pending > 0 && !map2.get(s.name)) ? map1.set(s.name,s) :  map2.set(s.name,s)
))
  console.log([...map1.values()])

答案 1 :(得分:1)

您可以试试吗?对我有用。

    Sub ChangeSelectionToUCase()
        ' MsgBox Selection.Range.text
        Selection.Range.Case = wdUpperCase
        ' MsgBox Selection.Range.text
    End Sub

答案 2 :(得分:0)

除了伪矩阵代码外,您还可以创建一个简单的过滤谓词函数,该函数接受一个条目,并在任何条件失败时短路。您需要检查违反条件而不是要求的条件。

只需在最后返回true

对于您的数据,由于您有一个对象数组(它们本身包含对象),因此您需要将每个组映射到一个约简,以便您可以滤除键值对(其中值(输入))不符合谓词的条件。减少只是一次映射和过滤。您需要减少操作,因为您无法通过键过滤对象。

const data = [{
  0: { id: 1, name: "A", required: 1, pending: 1 },
  1: { id: 2, name: "B", required: 0, pending: 0 }
}, {
  0: { id: 1, name: "A", required: 1, pending: 1 },
  1: { id: 2, name: "B", required: 1, pending: 1 },
  2: { id: 3, name: "C", required: 0, pending: 0 }
}]

const isRequiredAndPendingGreaterThanZero = (entry) => {
  if (entry == null) return false;
  if (entry.required !== 1) return false;
  if (entry.pending < 1) return false;
  return true;
}

console.log(data.map(group => {
  return Object.entries(group).reduce((res, entry) => {
    let [ key, value ] = entry;
    return isRequiredAndPendingGreaterThanZero(value)
      ? { ...res, [key]: value } : res;
  }, {});
}));
.as-console-wrapper { top: 0; max-height: 100% !important; }

这是一个更具动态性的版本,可以检查每个有效条件,并允许您为每个键定义条件。

此示例使用对象数组的简化数据结构,但可以轻松地使其适用于任何列表数据结构(无论是否分组)。

const data = [
  { id: 1, name: "A", required: 1, pending: 1 },
  { id: 2, name: "B", required: 1, pending: 1 },
  { id: 3, name: "C", required: 0, pending: 0 }
];

const isValid = (entry, criteria) => {
  if (entry == null) return false;
  return Object.keys(criteria).every(key => criteria[key](entry[key]));
}

console.log(data.filter(entry => isValid(entry, {
  required : v => v === 1,
  pending  : v => v > 0
})));
.as-console-wrapper { top: 0; max-height: 100% !important; }

答案 3 :(得分:0)

使用forEach并推送到结果数组。

const filter = (arr) => {
  const res = [];
  const track = {};
  arr.forEach((obj) =>
    Object.entries(obj).forEach(([i, item]) => {
      const isValid = ["required", "pending"].every((key) => item[key] > 0);
      if (isValid && !(item.name in track)) {
        res.push({ [i]: item });
      }
      track[item.name] = isValid;
    })
  );
  return res;
};

let arr1 = [
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 0, pending: 0 },
  },
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 1, pending: 1 },
    2: { id: 3, name: "C", required: 0, pending: 0 },
  },
];

let arr2 = [
      {
        0: { id: 1, name: "A", required: 1, pending: 1 },
        1: { id: 2, name: "B", required: 1, pending: 1 },
        2: { id: 3, name: "C", required: 0, pending: 0 }
      }
    ]
    
console.log(filter(arr1));
console.log('------------');
console.log(filter(arr2));

更新:输出不带索引。

const filter = (arr) => {
  const res = [];
  const track = {};
  arr.forEach((obj) =>
    Object.entries(obj).forEach(([i, item]) => {
      const isValid = ["required", "pending"].every((key) => item[key] > 0);
      if (isValid && !(item.name in track)) {
        // res.push({ [i]: item });
        res.push(item);
      }
      track[item.name] = isValid;
    })
  );
  return res;
};

let arr1 = [
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 0, pending: 0 },
  },
  {
    0: { id: 1, name: "A", required: 1, pending: 1 },
    1: { id: 2, name: "B", required: 1, pending: 1 },
    2: { id: 3, name: "C", required: 0, pending: 0 },
  },
];

let arr2 = [
      {
        0: { id: 1, name: "A", required: 1, pending: 1 },
        1: { id: 2, name: "B", required: 1, pending: 1 },
        2: { id: 3, name: "C", required: 0, pending: 0 }
      }
    ]
    
console.log(filter(arr1));
console.log('------------');
console.log(filter(arr2));

相关问题