从阵列中过滤掉数据的最佳方法

时间:2017-10-26 09:39:26

标签: javascript ecmascript-6 ramda.js

我想根据某些条件过滤掉数组中的数据。

检查两者是否已被检查' &安培; ' isPrimaryKey'是真的,如果重命名'不是空的然后在输出数组中需要显示重命名,否则显示名称。

以下代码对我来说非常合适。我想知道有没有更好的方法。

还想知道这种方法是否存在任何错误(使用map迭代有限数量的对象)

let columnList = [
  { id:1, name: "Id", rename: "", isChecked: true, isPrimaryKey: true },
  { id:2, name: "Name", isChecked: false, isPrimaryKey: true },
  { id:3, name: "age",  rename: "Age", isChecked: true, isPrimaryKey: true },
  { id:4, name: "Designation", isChecked: true, isPrimaryKey: false },
  { id:5, name: "Salary", isChecked: false, isPrimaryKey: true },
  { id:6, name: "Department", isChecked: true, isPrimaryKey: false },
  { id:7, name: "Project", isChecked: false, isPrimaryKey: false }
];

let data = columnList.map(d => {
  if(d.isChecked && d.isPrimaryKey) {
    return (d.rename && d.rename !== '') ? d.rename : d.name;
  }
});

data = data.filter(item => item);
console.log(data);
  

输出:[" Id","年龄"]

2 个答案:

答案 0 :(得分:2)

您应该使用array.reduce代替array.map + array.filter

  • Array.map - 此函数将返回带有返回值的n元素数组。它可以返回部分/已处理的值。
  • Array.filter - 此函数用于过滤数组中的项目。这将返回与案例匹配的n个元素,但不会更改/处理它们。
  • Array.reduce - 此函数用于减少数组中的项目数。在执行此操作时,您可以操纵项目并返回自定义值。

同样,对于需要检查rename是否可用的情况,然后返回,否则返回name,您可以使用.push(d.rename || d.name)

来实现

let columnList = [
  { id:1, name: "Id", rename: "", isChecked: true, isPrimaryKey: true },
  { id:2, name: "Name", isChecked: false, isPrimaryKey: true },
  { id:3, name: "age",  rename: "Age", isChecked: true, isPrimaryKey: true },
  { id:4, name: "Designation", isChecked: true, isPrimaryKey: false },
  { id:5, name: "Salary", isChecked: false, isPrimaryKey: true },
  { id:6, name: "Department", isChecked: true, isPrimaryKey: false },
  { id:7, name: "Project", isChecked: false, isPrimaryKey: false }
];

let data = columnList.reduce((p, d) => {
  if(d.isChecked && d.isPrimaryKey) {
    p.push(d.rename || d.name);
  }
  return p;
}, []);
console.log(data)

但是,如果你仍然希望选择Array.map + array.filter,你可以尝试这样的事情:

let columnList = [
  { id:1, name: "Id", rename: "", isChecked: true, isPrimaryKey: true },
  { id:2, name: "Name", isChecked: false, isPrimaryKey: true },
  { id:3, name: "age",  rename: "Age", isChecked: true, isPrimaryKey: true },
  { id:4, name: "Designation", isChecked: true, isPrimaryKey: false },
  { id:5, name: "Salary", isChecked: false, isPrimaryKey: true },
  { id:6, name: "Department", isChecked: true, isPrimaryKey: false },
  { id:7, name: "Project", isChecked: false, isPrimaryKey: false }
];

let data = columnList
  .filter(d => d.isChecked && d.isPrimaryKey)
  .map(d => d.rename || d.name);

console.log(data)

区别在于阅读。当你阅读它时,你将它读作,

  

您正在按isCheckedisPrimaryKey过滤列表,并且已过滤,您将返回renamename

这些函数是函数式编程的一部分,当它们提高代码的可读性时,它们的美感就来了。在你的代码中,读者必须阅读逻辑来理解你想要达到的目标,这就是目的。

答案 1 :(得分:2)

Rajesh回答的后续行动:如果你想要filter的干净代码 - 然后 - map,但又不想添加额外的迭代,Ramda提供在许多列表处理函数中支持transducers,包括mapfilter。以下版本将迭代列表一次,检查每个步骤是否与项目匹配过滤器,以及是否通过传递给map的函数选择了正确的属性。

但是代码仍然很好地考虑到了过滤步骤,然后是映射步骤。



let columnList = [
  { id:1, name: "Id", rename: "", isChecked: true, isPrimaryKey: true },
  { id:2, name: "Name", isChecked: false, isPrimaryKey: true },
  { id:3, name: "age",  rename: "Age", isChecked: true, isPrimaryKey: true },
  { id:4, name: "Designation", isChecked: true, isPrimaryKey: false },
  { id:5, name: "Salary", isChecked: false, isPrimaryKey: true },
  { id:6, name: "Department", isChecked: true, isPrimaryKey: false },
  { id:7, name: "Project", isChecked: false, isPrimaryKey: false }
];


const getCols = R.into([], R.compose(
  R.filter(d => d.isChecked && d.isPrimaryKey),
  R.map(d => d.rename || d.name)
))

const cols = getCols(columnList)

console.log(cols)

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
&#13;
&#13;
&#13;

您还询问您的方法是否存在问题。可能有。除了已经讨论过的额外迭代之外,还有两个问题:首先,使用filteritem => item不仅会禁用null / undefined值,还会禁止任何错误-y值,最值得注意的是0。因此,如果您尝试提取0可能是合理值的列表,则会将其排除。其次,在函数式编程中,它通常被认为是重新分配变量的坏习惯。所以data = data.filter(...)非常不满意。