从数组中过滤数据的最佳方法
Best Approach to filter out data from array
我想根据特定条件过滤掉数组中的数据。
检查 'isChecked' 和 'isPrimaryKey' 是否为真,如果 'rename' 不为空,则在输出数组中需要显示重命名,否则显示名称。
下面的代码非常适合我。我想知道有没有更好的方法。
还想知道这种方法有什么问题吗(使用 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);
Output: ["Id", "Age"]
您应该使用 array.reduce
而不是 array.map
+ array.filter
。
- Array.map - 此函数将 return 一个 n 元素的数组,其值为 return。它可以 return partial/processed 值。
- Array.filter - 此函数用于过滤数组中的项目。这将 return n 个匹配大小写的元素,但不会 change/process 它们。
- Array.reduce - 此函数旨在减少数组中的项目数。在这样做时,您可以操纵项目和 return 自定义值。
另外,对于需要检查 rename
是否可用然后 return 否则 return 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)
区别在于阅读。当你读它的时候,你读它是,
You are filtering list by isChecked
and isPrimaryKey
and the from the filtered, you are returning either rename
or name
这些函数是函数式编程的一部分,它们的美在于提高代码的可读性。在您的代码中,reader 将必须阅读逻辑以了解您要实现的目标,这超出了目的。
Rajesh 回答的后续:如果您想要 filter
-then-map
的干净代码,但不想添加额外的迭代,Ramda 提供对 transducers in many of its list-handling functions, including map
and filter
。以下版本将迭代列表一次,检查每一步是否项目匹配过滤器,以及是否通过传递给 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>
您还询问了您的方法是否存在问题。可能有。除了已经讨论过的额外迭代之外,还有两个问题:首先,将 filter
与 item => item
一起使用不仅会禁止 null
/undefined
值,还会禁止任何 false -y 值,最显着的是 0
。因此,如果您尝试提取一个列表,其中 0
可能是一个合理的值,这将排除它。其次,在函数式编程中,重新分配变量通常被认为是一种坏习惯。所以 data = data.filter(...)
很不受欢迎。
我想根据特定条件过滤掉数组中的数据。
检查 'isChecked' 和 'isPrimaryKey' 是否为真,如果 'rename' 不为空,则在输出数组中需要显示重命名,否则显示名称。
下面的代码非常适合我。我想知道有没有更好的方法。
还想知道这种方法有什么问题吗(使用 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);
Output: ["Id", "Age"]
您应该使用 array.reduce
而不是 array.map
+ array.filter
。
- Array.map - 此函数将 return 一个 n 元素的数组,其值为 return。它可以 return partial/processed 值。
- Array.filter - 此函数用于过滤数组中的项目。这将 return n 个匹配大小写的元素,但不会 change/process 它们。
- Array.reduce - 此函数旨在减少数组中的项目数。在这样做时,您可以操纵项目和 return 自定义值。
另外,对于需要检查 rename
是否可用然后 return 否则 return 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)
区别在于阅读。当你读它的时候,你读它是,
You are filtering list by
isChecked
andisPrimaryKey
and the from the filtered, you are returning eitherrename
orname
这些函数是函数式编程的一部分,它们的美在于提高代码的可读性。在您的代码中,reader 将必须阅读逻辑以了解您要实现的目标,这超出了目的。
Rajesh 回答的后续:如果您想要 filter
-then-map
的干净代码,但不想添加额外的迭代,Ramda 提供对 transducers in many of its list-handling functions, including map
and filter
。以下版本将迭代列表一次,检查每一步是否项目匹配过滤器,以及是否通过传递给 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>
您还询问了您的方法是否存在问题。可能有。除了已经讨论过的额外迭代之外,还有两个问题:首先,将 filter
与 item => item
一起使用不仅会禁止 null
/undefined
值,还会禁止任何 false -y 值,最显着的是 0
。因此,如果您尝试提取一个列表,其中 0
可能是一个合理的值,这将排除它。其次,在函数式编程中,重新分配变量通常被认为是一种坏习惯。所以 data = data.filter(...)
很不受欢迎。