您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > javascript

提升 JavaScript 水平的 9 个基本数组难题 [JS 基础]

时间:2023-01-08 11:39:15  来源:今日头条  作者:启辰8

 

成为出色的问题解决者(这就是开发人员)没有捷径可走。

精通是以练习为代价的。 由于算法和数据结构构成了每个软件的支柱,因此练习它们应该是您的首要任务。 作为最常用的存储值序列的数据结构,数组是必不可少的。

今天,我们将通过学习如何来磨练我们的技能:

*展平一个数组
* 删除数组中的重复项
*从对象数组中删除重复项
*对对象数组进行排序
*合并两个数组
*返回两个数组之间的差异
*检查数组是否包含重复元素
*返回两个数组的交集
*查找数组中最长的字符串

俗话说“熟能生巧”。 让我们搞定它

如何展平数组:

最简单的方法是使用内置的 .flat() 方法。flat() 方法采用可选的最大深度参数。

例如,给定以下数组:

const arr = [1, 2, [3, 4], [[5, 6], [7, 8]]];

展平的代码是:

const flattened = arr.flat(2); //最大深度
console.log(flattened); // [1, 2, 3, 4, 5, 6, 7, 8]

flat() 方法返回一个新数组,所有子数组以递归方式连接到指定深度。

您还可以创建自己的递归函数,迭代数组的元素并将它们添加到新数组中,一次一个。

  • 如果一个元素是一个数组,该函数应该以该元素作为参数调用自身,然后将结果数组连接到新数组。
  • 如果一个元素不是数组,函数应该简单地将它添加到新数组中。

这是一个示例,说明如何编写递归函数来展平数组:

function flatten(arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      result = result.concat(flatten(arr[i]));
    } else {
      result.push(arr[i]);
    }
  }
  return result;
}

const arr = [1, [2, [3, [4]]], 5];
console.log(flatten(arr)); // [1, 2, 3, 4, 5]

您可以使用 .reduce() 方法和三元运算符使此函数更加简洁。

function flatten(arr) {
  return arr.reduce((accumulator, currentItem) => 
    Array.isArray(currentItem)
      ? accumulator.concat(flatten(currentItem))
      : accumulator.concat(currentItem), 
  []);
}

此函数具有线性时间复杂度(这意味着它对大型数组很有效)。它还具有恒定的空间复杂度(这意味着它不会随着数组大小的增加而占用更多内存)。

如何从数组中删除重复项:

到目前为止,删除数组重复项的最简单和更简洁的方法是使用 Set 对象。

Set 对象仅存储唯一值,因此您可以从数组创建一个新集合,然后使用 Array.from() 方法将该集合转换回数组。

这是您可以使用 Set 对象执行此操作的一种方法:

const arr = [1, 2, 3, 1, 2, 3, 4, 5];

const unique = Array.from(new Set(arr));

console.log(unique); // [1, 2, 3, 4, 5]

您还可以使用我最喜爱的 .reduce()

const arr = [1, 2, 3, 1, 2, 3, 4, 5]

arr.reduce((accumulator, currentItem) => {
    if (!accumulator.includes(currentItem))
        accumulator.push(currentItem)
    return accumulator
},[])

如何对对象数组进行排序

要对对象数组进行排序,您必须从对象中选择一个属性来对数组进行排序。

然后,您可以调用 .sort() 并将其传递给比较器函数。

这是比较器函数的工作原理:

  • 需要两个参数
  • 如果第一个应该在第二个之前出现,则返回负值
  • 如果第一个应该在第二个之后,它返回一个正值
  • 如果值相等,则返回 0。

以下是如何根据 name 属性的值对对象数组进行排序:

const arr = [  
  {name: 'Bob', age: 30},  
  {name: 'Alice', age: 25},  
  {name: 'Charlie', age: 35}
];

arr.sort((a, b) => {
  if (a.name < b.name) { //你可以根据任意属性排序
    return -1;
  } else if (a.name > b.name) {
    return 1;
  } else {
    return 0;
  }
});

/*
[
  {name: 'Alice', age: 25}, 
  {name: 'Bob', age: 30}, 
  {name: 'Charlie', age: 35}
] */

您还可以使用三元运算符来制作单行版本:

arr.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);

注意:有时嵌套的三元组可能难以阅读。

请记住,sort() 方法会修改原始数组,因此如果您想保留原始数组,您应该先复制它。

如何合并2个数组

要合并两个数组,您可以使用 concat() 方法。concat() 方法返回一个包含两个数组元素的新数组。

以下是如何使用 concat() 合并两个数组的示例:

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

const merged = arr1.concat(arr2);
console.log(merged); // [1, 2, 3, 4, 5, 6]

更高级的或者更确切地说是 ES6 版本使用扩展运算符 (...)。扩展运算符将数组的元素扩展为单独的参数。

这就是它的样子

const merged = [...arr1, ...arr2];
console.log(merged); // [1, 2, 3, 4, 5, 6]

有两种方法:

  • 创建一个包含两个数组元素的新数组
  • 不要修改原始数组。

如果你不介意修改源数组,您可以简单地使用 .push() 将另一个数组的元素添加到第一个数组的末尾。

arr1.push(...arr2);
console.log(arr1); // [1, 2, 3, 4, 5, 6]

返回 2 个数组之间的差异

有以下几种区别:

  • 非对称的
  • 对称的

非对称

  • 在第一个数组中但不在第二个数组中的元素

对称

  • 在第一个数组中但不在第二个数组中的元素,以及在第二个数组中但不在第一个数组中的元素

以下是如何使用 filter() 方法查找两个数组之间的非对称差异:

const arr1 = [1, 2, 3, 4, 5];
const arr2 = [3, 4, 5, 6, 7];

const difference = arr1.filter(x => !arr2.includes(x));
console.log(difference); // [1, 2]

以下是为了获得对称差异:

const arr1 = [1, 2, 3, 4, 5];
const arr2 = [3, 4, 5, 6, 7];

const difference = arr1
    .filter(x => !arr2.includes(x))
    .concat(arr2.filter(x => !arr1.includes(x)));

console.log(difference); // [1, 2, 6, 7]

这种方法返回一个新数组并且不修改原始数组。

或者,您可以使用 Set 对象及其 .has() 而不是 .includes()

非对称差异:

const set = new Set(arr2);
const difference = arr1.filter(x => !set.has(x));
console.log(difference); // [1, 2]

对称差异:

const set = new Set(arr2);
const set1 = new Set(arr1)
const difference = arr1
    .filter(x => !set.has(x))
    .concat(arr2.filter(x => !set1.has(x)));

console.log(difference); // [1, 2, 6, 7]

如何检查数组是否包含重复元素

最简单的方法是使用 Set 对象和 size 属性。

Set 对象仅存储唯一值,因此您可以从数组创建一个集合并将该集合的大小与原始数组的大小进行比较。

如果集合的大小小于数组的大小,则意味着数组包含重复元素。

以下是您的操作方式:

const arr = [1, 2, 3, 4, 5, 5];

const hasDuplicates = new Set(arr).size !== arr.length;
console.log(hasDuplicates); // true

您可以使用对象(也称为散列或字典)实现相同的目的

当您遍历数组时,您将当前值设置为键,将 true 设置为键的值。

如果您尝试访问一个键并且那里已经有一个值,则意味着您找到了一个重复项。

这是其中一种方法:

const hasDuplicates = (arr) => {
    let hash = {}
   for(let i = 0; i < arr.length; i++){
       if(!hash[arr[i]]){
           hash[arr[i]] = true
       } else {
           return true;
       }
   }
    return false
}

console.log(hasDuplicates(arr)); // true

这两种方法都创建一个新对象(集合或哈希对象)并且不修改原始数组。它们还具有线性时间复杂度(它们对大型数组很有效)。

如何返回两个数组之间的交集

最常见的方法是使用 filter() 和 includes()。

代码如下:

const arr1 = [1, 2, 3, 4, 5];
const arr2 = [3, 4, 5, 6, 7];

const intersection = arr1.filter(x => arr2.includes(x));
console.log(intersection); // [3, 4, 5]

这种方法返回一个新数组并且不修改原始数组。

作为替代方案,您可以(再次)使用 Set 对象和 .has() 方法

const set = new Set(arr2);
const intersection = arr1.filter(x => set.has(x));
console.log(intersection); // [3, 4, 5]

你看到模式了吗? 每当使用普通对象解决问题时,您都可以使用 Set创建一个版本,反之亦然。

如何找到数组中最长的字符串

为此,您可以使用我们流行的 .reduce() 方法和一个函数来比较这些值。

比较器函数将当前字符串的长度与前一个最长字符串的长度进行比较,如果更长则返回当前字符串,否则返回前一个最长字符串。

你可以这样做:

const arr = ['short', 'medium', 'long', 'longest'];

const longest = arr.reduce((acc, x) => x.length > acc.length ? x : acc, '');
console.log(longest); // 'longest'

这种方法创建一个新变量(acc 或累加器)并且不修改原始数组。

时间复杂度是线性的(意味着它对大型数组是有效的)。

同样可以通过使用 sort() 方法和扩展运算符 (...) 来更简洁地找到数组中最长的字符串:

const longest = [...arr].sort((a, b) => b.length - a.length)[0];
console.log(longest); // 'longest'

总结

在本文中我们介绍了:

*展平一个数组
* 删除数组中的重复项
*从对象数组中删除重复项
*对对象数组进行排序
*合并两个数组
*返回两个数组之间的差异
*检查数组是否包含重复元素
*返回两个数组的交集
*查找数组中最长的字符串

谢谢阅读!



Tags: JavaScript   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
17 个你需要知道的 JavaScript 优化技巧
你可能一直在使用JavaScript搞开发,但很多时候你可能对它提供的最新功能并不感冒,尽管这些功能在无需编写额外代码的情况下就可以解决你的问题。作为前端开发人员,我们必须了解...【详细内容】
2024-04-03  Search: JavaScript  点击:(6)  评论:(0)  加入收藏
你不可不知的 15 个 JavaScript 小贴士
在掌握如何编写JavaScript代码之后,那么就进阶到实践&mdash;&mdash;如何真正地解决问题。我们需要更改JS代码使其更简单、更易于阅读,因为这样的程序更易于团队成员之间紧密协...【详细内容】
2024-03-21  Search: JavaScript  点击:(27)  评论:(0)  加入收藏
使用 JavaScript 清理我的 200GB iCloud,有了一个意外发现!
本文作者在综合成本因素之下,决定用 Java 脚本来清理一下自己的 iCloud,结果却有了一个意外发现,即在 iCloud 中上传同一个视频和删除此视频之后,iCloud 的空间并不一致,这到底是...【详细内容】
2024-01-11  Search: JavaScript  点击:(99)  评论:(0)  加入收藏
创建一个双模式跨运行时的 JavaScript 包,你学会了吗
本文将指导你发布双模式、跨运行时的 JavaScript 包。了解如何创建与 ESM 和 CommonJS 以及 Node.js、Deno 和浏览器等不同运行时兼容的库。随着 JavaScript 开发的不断发展...【详细内容】
2023-12-27  Search: JavaScript  点击:(159)  评论:(0)  加入收藏
五种在 JavaScript 中创建对象的方法
在 JavaScript 中,对象是多功能工具,可以通过多种方式创建,每种方式适合不同的场景。了解何时使用每种方法是编写高效且可维护的 JavaScript 代码的关键。让我们探讨在 JavaScr...【详细内容】
2023-11-23  Search: JavaScript  点击:(239)  评论:(0)  加入收藏
通过示例解释所有 JavaScript 数组方法
作为一名程序员,我们的工作是写有效的代码,但是仅仅写有效的代码,这还不够。如果想成为优秀的程序员,我们还需要编写可维护和可扩展的代码。JavaScript为我们提供了很多可以用来...【详细内容】
2023-11-15  Search: JavaScript  点击:(264)  评论:(0)  加入收藏
Jest:目前最广泛使用的前端 JavaScript 测试框架
Jest 是一个简单易用的 JavaScript 测试框架。最初由 Meta 公司团队维护。2022 年 5 月,Meta 公司正式将自己的开源项目Jest 移交给 OpenJS Foundation[1],这表示 Jest 由公司...【详细内容】
2023-11-08  Search: JavaScript  点击:(341)  评论:(0)  加入收藏
19 种常见的 JavaScript 和 Node.js 错误
译者 | 刘汪洋审校 | 重楼速度、性能和响应性在 Web 开发中起着至关重要的作用,尤其是在使用 JavaScript 和 Node.js 开发时尤为重要。如果一个网站响应缓慢或界面卡顿,就会让...【详细内容】
2023-11-03  Search: JavaScript  点击:(194)  评论:(0)  加入收藏
现在就可以使用的 20 个 JavaScript 技巧和窍门
今天探讨 20 种 JavaScript 技巧和窍门,每种技巧和窍门都有通俗易懂的示例。让我们一起来提升你的 JavaScript 技能吧!1. 解构魔法:轻松提取值解构允许你轻松地从数组或对象中...【详细内容】
2023-10-18  Search: JavaScript  点击:(261)  评论:(0)  加入收藏
处理 JavaScript 对象的十个技巧
对象是JavaScript程序的基本结构,用于构建类和复杂数据,是面向对象编程的组成部分。我作为一名全栈软件开发人员,在过去的五年多时间里,每天都在使用JavaScript。对象在JavaSc...【详细内容】
2023-10-16  Search: JavaScript  点击:(266)  评论:(0)  加入收藏
▌简易百科推荐
JavaScript的异步编程常见模式
在JavaScript中,异步编程是一种处理长时间运行操作(如网络请求或I/O操作)的常见方式。它允许程序在等待这些操作完成时继续执行其他任务,从而提高应用程序的响应性和性能。JavaS...【详细内容】
2024-04-12  靳国梁    Tags:JavaScript   点击:(2)  评论:(0)  加入收藏
17 个你需要知道的 JavaScript 优化技巧
你可能一直在使用JavaScript搞开发,但很多时候你可能对它提供的最新功能并不感冒,尽管这些功能在无需编写额外代码的情况下就可以解决你的问题。作为前端开发人员,我们必须了解...【详细内容】
2024-04-03  前端新世界  微信公众号  Tags:JavaScript   点击:(6)  评论:(0)  加入收藏
你不可不知的 15 个 JavaScript 小贴士
在掌握如何编写JavaScript代码之后,那么就进阶到实践&mdash;&mdash;如何真正地解决问题。我们需要更改JS代码使其更简单、更易于阅读,因为这样的程序更易于团队成员之间紧密协...【详细内容】
2024-03-21  前端新世界  微信公众号  Tags:JavaScript   点击:(27)  评论:(0)  加入收藏
又出新JS运行时了!JS运行时大盘点
Node.js是基于Google V8引擎的JavaScript运行时,以非阻塞I/O和事件驱动架构为特色,实现全栈开发。它跨平台且拥有丰富的生态系统,但也面临安全性、TypeScript支持和性能等挑战...【详细内容】
2024-03-21  前端充电宝  微信公众号  Tags:JS   点击:(26)  评论:(0)  加入收藏
构建一个通用灵活的JavaScript插件系统?看完你也会!
在软件开发中,插件系统为应用程序提供了巨大的灵活性和可扩展性。它们允许开发者在不修改核心代码的情况下扩展和定制应用程序的功能。本文将详细介绍如何构建一个灵活的Java...【详细内容】
2024-03-20  前端历险记  微信公众号  Tags:JavaScript   点击:(20)  评论:(0)  加入收藏
对JavaScript代码压缩有什么好处?
对JavaScript代码进行压缩主要带来以下好处: 减小文件大小:通过移除代码中的空白符、换行符、注释,以及缩短变量名等方式,可以显著减小JavaScript文件的大小。这有助于减少网页...【详细内容】
2024-03-13  WangLiwen    Tags:JavaScript   点击:(2)  评论:(0)  加入收藏
跨端轻量JavaScript引擎的实现与探索
一、JavaScript 1.JavaScript语言JavaScript是ECMAScript的实现,由ECMA 39(欧洲计算机制造商协会39号技术委员会)负责制定ECMAScript标准。ECMAScript发展史: 2.JavaScript...【详细内容】
2024-03-12  京东云开发者    Tags:JavaScript   点击:(2)  评论:(0)  加入收藏
面向AI工程的五大JavaScript工具
令许多人惊讶的是,一向在Web开发领域中大放异彩的JavaScript在开发使用大语言模型(LLM)的应用程序方面同样大有价值。我们在本文中将介绍面向AI工程的五大工具,并为希望将LLM...【详细内容】
2024-02-06    51CTO  Tags:JavaScript   点击:(53)  评论:(0)  加入收藏
JS小知识,使用这6个小技巧,避免过多的使用 if 语句
最近在重构我的代码时,我注意到早期的代码使用了太多的 if 语句,达到了我以前从未见过的程度。这就是为什么我认为分享这些可以帮助我们避免使用过多 if 语句的简单技巧很重要...【详细内容】
2024-01-30  前端达人  今日头条  Tags:JS   点击:(58)  评论:(0)  加入收藏
18个JavaScript技巧:编写简洁高效的代码
本文翻译自 18 JavaScript Tips : You Should Know for Clean and Efficient Code,作者:Shefali, 略有删改。在这篇文章中,我将分享18个JavaScript技巧,以及一些你应该知道的示例...【详细内容】
2024-01-30  南城大前端  微信公众号  Tags:JavaScript   点击:(71)  评论:(0)  加入收藏
站内最新
站内热门
站内头条