JavaScript 中 filter() 和 find() 的区别对比

filter() 和 find() 都是 JavaScript 数组的高阶函数,用于搜索数组元素,但它们有几个关键区别:

1. 基本区别

特性filter()find()
返回值新数组(包含所有匹配元素)第一个匹配的元素(不是数组)
空结果返回空数组 []返回 undefined
用途筛选多个符合条件的元素查找第一个符合条件的元素

2. 代码示例对比

示例数组

const users = [
  { id: 1, name: 'Alice', active: true },
  { id: 2, name: 'Bob', active: false },
  { id: 3, name: 'Charlie', active: true },
  { id: 4, name: 'David', active: true }
];

使用 filter()

// 找出所有活跃用户
const activeUsers = users.filter(user => user.active);
console.log(activeUsers);
// 输出: [
//   {id: 1, name: 'Alice', active: true},
//   {id: 3, name: 'Charlie', active: true},
//   {id: 4, name: 'David', active: true}
// ]

// 没有匹配项时
const noUsers = users.filter(user => user.age > 100);
console.log(noUsers); // 输出: []

使用 find()

// 查找第一个活跃用户
const firstActive = users.find(user => user.active);
console.log(firstActive);
// 输出: {id: 1, name: 'Alice', active: true}

// 没有匹配项时
const notFound = users.find(user => user.age > 100);
console.log(notFound); // 输出: undefined

3. 性能考虑

  • filter() 会遍历整个数组,即使已经找到所有符合条件的元素

  • find() 在找到第一个匹配项后立即停止遍历

// 性能测试
const bigArray = Array(1000000).fill(0).map((_, i) => i);

console.time('filter');
bigArray.filter(x => x === 500000); // 会检查所有元素
console.timeEnd('filter'); // 输出: filter: 5.22509765625 ms

console.time('find');
bigArray.find(x => x === 500000); // 找到后立即停止
console.timeEnd('find'); // 输出: find: 2.56298828125 ms

4. 链式调用差异

// filter可以继续链式调用
users
  .filter(user => user.active)
  .map(user => user.name)
  .forEach(name => console.log(name));
// 输出: 
// Alice
// Charlie
// David

// find不能链式调用数组方法(因为返回的是元素)
const userName = users.find(user => user.id === 2).name; // 直接访问属性
console.log(userName) //输出: Bob

5. 实际应用场景

适合使用 filter() 的情况:

  • 需要获取所有匹配项

  • 需要对结果集进行进一步操作(如再过滤、映射等)

  • 需要确保总是返回数组(便于后续处理)

// 获取所有未完成的任务
const incompleteTasks = tasks.filter(task => !task.completed);

// 结合map使用
const activeUserNames = users
  .filter(user => user.active)
  .map(user => user.name);

适合使用 find() 的情况:

  • 只需要第一个匹配项

  • 检查数组中是否存在某个元素

  • 查找特定ID的对象

// 查找特定用户
const user = users.find(user => user.id === 3);
console.log(user) //输出: { id: 3, name: 'Charlie', active: true },

// 检查是否存在管理员
const hasAdmin = users.find(user => user.role === 'admin') !== undefined;
console.log(hasAdmin ) //输出: false

6. 特殊注意事项

  1. 引用类型:两者都返回原始数组中的引用(不会创建副本)

    const found = users.find(u => u.id === 1);
    found.name = 'Alex'; // 会修改原数组中的对象
    console.log(users) 
    //输出: [
    //  { id: 1, name: 'Alex', active: true },
    //  { id: 2, name: 'Bob', active: false },
    //  { id: 3, name: 'Charlie', active: true },
    //  { id: 4, name: 'David', active: true }
    // ]
  2. 稀疏数组

    const sparse = [1, , 3];
    sparse.find(x => true); // 1 (跳过空位)
    sparse.filter(x => true); // [1, 3] (跳过空位)
  3. this绑定:两者都接受第二个参数用于设置回调函数的this

    const checker = {
      threshold: 2,
      check(num) { return num > this.threshold; }
    };
    
    [1, 2, 3].find(checker.check, checker); // 3

总结选择

  • 需要 多个结果 → 用 filter()

  • 只需要 第一个结果 → 用 find()

  • 需要 性能优化(大数据集) → 优先考虑 find()

  • 需要 确保数组返回值 → 用 filter()

  • 进行 链式操作 → 用 filter()

### 平行四边形图像数据集 在遥感目标检测领域,存在一些专门用于复杂形状物体识别的数据集,其中部分可能包含平行四边形的目标。例如,在 **DOTA 数据集** 中,目标通常被标注为旋转矩形或多边形形式[^1]。这些多边形可以近似表示为平行四边形或其他复杂的几何图形。 #### DOTA 数据集 DOTA(Dataset for Object Detection in Aerial Images)是一个广泛使用的航拍图像数据集,涵盖了多种类型的对象类别,其标注方式支持任意方向的边界框以及更灵活的多边形描述。如果研究的重点在于平行四边形结构,则可以从该数据集中筛选出具有此类特征的对象实例。具体来说: - DOTA 提供了丰富的场景覆盖范围多样化的标签定义。 - 它不仅限于水平矩形框,还扩展到了倾斜角度下的目标表达形式——即所谓的 “rotation and horizontal detection”。 对于进一步探索特定形态如平行四边形的应用需求,可以通过自定义脚本提取符合条件的部分子集。下面展示了一个简单的 Python 脚本来演示如何读取 JSON 文件并过滤满足条件的记录: ```python import json def filter_parallel_quadrilaterals(json_file_path): with open(json_file_path, 'r') as f: data = json.load(f) filtered_objects = [] for obj in data['objects']: points = obj['points'] # Check if the shape forms a parallelogram by verifying opposite sides are parallel. vector_ab = (points[1][0]-points[0][0], points[1][1]-points[0][1]) vector_dc = (points[3][0]-points[2][0], points[3][1]-points[2][1]) vector_ad = (points[2][0]-points[0][0], points[2][1]-points[0][1]) vector_bc = (points[3][0]-points[1][0], points[3][1]-points[1][1]) if abs(vector_ab[0]*vector_dc[1] - vector_ab[1]*vector_dc[0]) < 1e-6 \ and abs(vector_ad[0]*vector_bc[1] - vector_ad[1]*vector_bc[0]) < 1e-6: filtered_objects.append(obj) return filtered_objects filtered_data = filter_parallel_quadrilaterals('path_to_dota_annotations.json') print(len(filtered_data), "parallelograms found.") ``` 此外,关于最新的 SOTA 方法及其对应的性能指标 mAP 值等内容可参阅另一篇综述材料[^2],它总结了一系列针对不同版本任务的最佳实践方案,并提供了链接至相应实现代码库的信息资源列表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值