javascript实现 文本过滤 找出一段文本中的所有数字/数值 并在去重后排序

本文介绍了如何使用JavaScript在浏览器控制台中从文本中提取正整数,去除重复并进行排序。通过String.prototype.match()方法匹配数字,利用Set去重,再使用Array.prototype.sort()自定义比较函数进行排序。此外,还探讨了对于包含小数或其他格式数值的处理方法,以及在大数据量场景下如何选择合适的TypedArray类型进行排序。
摘要由CSDN通过智能技术生成

Intro

一个小需求,我有一个文本文件/一段文本,其中混杂有多组不尽相同的正整数(暂时不考虑负数/小数/科学计数法表示的数值)。
我需要:

  1. 提取出其中所有的数字,得到一个数值的集合。
  2. 对出现的数字去重,得到一个数值的集合。
  3. 对去重后的数值集合排序,得到最终结果。

举个例子:在一段文本中随意插入一些数值,作为demoStringValue。

孤始举孝廉,年少,自以本非岩穴知名之士,恐为海内人之所见凡愚,欲为一郡守,好作政教,以建立名誉,使世士明知之;故在济南,始除残去秽,平心选举,违迕诸常侍。以为强豪所忿,2914365765恐致家祸,故以病还。
去官之后,年纪尚少,顾视同岁中,年有213五十,未名为老。内自图之,从此却去二十年,待天下清,乃与同岁中始举者等耳。故以四时归乡里,于谯东五十里筑精舍,欲秋夏读书,冬春射猎,求底下之地,欲以泥水自蔽123,绝宾客往来之望。然不能得如意。234353
后徵为都尉,迁典军校尉435,意遂更欲为国家讨贼立功,欲望封侯作征西将军897,然后题墓道言“汉故征西将军曹侯之墓”,此其志也。而遭值董卓之难,兴举义兵。是时合兵能多得耳,然常自损,不欲多之;所以然者,多兵意盛,与强4敌争,倘更为祸始。故3汴水之战数千,后还到扬州更募,亦复不过三千人,此其本志有24限也。
后领兖州,破降黄巾三十万众。又袁术僭号于九江,下皆称臣,名门曰建号门,衣4被皆3423为天子之制,两妇预争为皇后67。志计已定,人有劝术使遂即帝位,露布天下,答言“曹公尚在,未可也”。后孤讨禽其四将,获其人众,遂使术穷亡解沮,发病而死。及至袁绍据河北,兵势强盛,孤自度势,实不敌之;但计投死为国,以义灭身87,足垂于后。幸而破绍,枭其二子。又刘表自以为宗室,包藏342奸心,乍前乍却,以观世事,据有当州,孤复45645定之,遂平天下。身为宰相,人臣之贵已极,意望已过矣)。
今孤言此,若为自大,欲人言尽,故98706无讳7耳。设使国家无有孤,1不知当几人称帝,几人称王!45或者2342人见2孤强盛,又性不信天命之事,恐私心相评,言有不逊之志,妄相忖度,每用耿耿。齐桓、晋文所以垂称至今日者,以其兵势广大,犹能奉事周室也8。《论语》云:“三分123天下有其二,以服事殷,周76之德可谓至德矣。”夫能以大事小也1。昔乐毅走赵,赵王欲与之图燕。乐毅伏而垂泣,对曰:“臣事昭王,犹事大王;臣若获戾,放在他国,没世然后已,不4654忍谋赵之徒隶,况燕后嗣乎!”胡亥之杀蒙恬也,恬曰:“自吾先人及至子孙,积信于秦三世矣;今臣将兵三十余万,其势足以背叛,然自知必死而守义者,不敢辱先人之教以忘先王也。”孤每读此二人书,未尝不怆然流涕也。孤祖、父以至孤身,皆当亲重之任,可谓见信者矣,以及子桓兄弟,过于三世矣。46547
孤非徒对诸君说此也,常以语245妻妾,皆令1231深知此意。孤谓之言:“顾我万年之后,汝曹皆当出嫁,欲令传道我0心,使他人皆知之。”孤此言皆肝鬲之要也。所以勤勤恳恳叙心腹者,见周公有《金縢》之书以6自明,恐人不信之故。然欲孤便尔委捐所典兵众,以还执76事,归就6786武平侯国,实不可也。何者456?诚恐己离兵为人所祸也。既为子孙计,又己败则国家倾危,是以不得慕虚名而处实祸,此所不得为也。前朝恩封三子为侯,固辞不受,今更欲受之,非欲复以为荣,欲以为外援,为万安计。
孤闻介推之避晋封,申胥之逃楚赏,未尝不舍书而叹,有以自省也。奉国威灵,仗钺征伐,推弱67567以克强,处小而禽大。意之所图,动无违事,心之所虑,何向不济,遂荡平天下,不辱主命。可谓天助汉室,非人力也。然封兼四县,食户三5万,何德堪之!江湖未静,不可让位;至于邑土,可得而辞。今上还阳夏、柘、苦三县户二万,但食武平万户,且以分损谤议,少减孤之责也。
(出自《三国志•武帝纪》裴松之注本。)[1]

经由以下两行代码:

a = `demoStringValue`
[...new Set(a.match(/\d+/g))].sort((a, b) => a-b)

就可以提取出该段文本中所有的数字,并去重+排序:
['0', '1', '2', '3', '4', '5', '6', '7', '8', '24', '45', '67', '76', '87', '123', '213', '245', '342', '435', '456', '897', '1231', '2342', '3423', '4654', '6786', '45645', '46547', '67567', '98706', '234353', '2914365765']

在这里插入图片描述

浏览器控制台 JavaScript API测试

从一串文本中按照某种模式提取出匹配的子字符串 String.prototype.match(regexp)

在这里插入图片描述先用反引号包围我们的字符串,定义一个字符串变量a。(使用反引号不用考虑原本字符串内容中的单引号/双引号转义)。

String.prototype.match(regexp) 用于:在字符串对象中,按照给定的正则表达式模式,依次查找匹配成功的子字符串。
注意正则表达式的flag:g表示global,在字符串全局去匹配。不加的话,只匹配到第一个,就会马上返回。

数组去重 Array–>Set

在这里插入图片描述Array–>Set: 数组对象直接作为Set构造方法的入参,可以对Array中的元素去重
var setObj = new Set(arrayObject)
Set–>Array: 有好几种方法。

var set = ...;

var arr1 = [...setObj];	// 解构赋值
var arr2 = new Array(...setObj);	// 解构赋值 + Array 构造方法 
var arr3 = new Array([...setObj]);

数组排序 Array.prototype.sort(compareFn)

在这里插入图片描述
Array.prototype.sort(compareFn) 数组对象本来就有一个sort方法。
但是sort方法默认的实现不一定能满足需求。
比如在本例中,该数组实际上是一个 String[] ,只不过每个String元素的值是数值字面量。
但是sort方法依然按照字符串的比较方法对元素进行排序(排序规则取决于当前的字符集 Character Set 和使用的校对集 collation)。
可以自己传入一个 var compareFn = function(a, b) { return a - b; } ,按照数值规范对元素排序。

流程总结

a = `......`;	// 1
a.match(/\d+/g);	// 2
new Set(a.match(/\d+/g));	// 3
[...new Set(a.match(/\d+/g))];	// 4
[...new Set(a.match(/\d+/g))].sort();	// 5
[...new Set(a.match(/\d+/g))].sort((a, b) => a-b);	// 6

共6行:

  1. 使用反引号,用将要处理的文本对其赋值;
  2. 使用 String.prototype.match(regexp) 提取出其中的数值字符串(整数);
  3. Array --> Set ;
  4. Set --> Array
  5. Array.prototype.sort() 使用默认的sort规则。
  6. 自定义compareFn规则。

Other case

不自己指定 compareFn ,有什么办法?

Array.prototype.sort() 不能满足需求,但是:
Uint32Array.prototype.sort() 可以直接满足需求。

在这里插入图片描述
new Uint32Array([...new Set(a.match(/\d+/g))]).sort()

如果要提取的数值不止正整数,还有小数/其他格式,如何操作?

/\d+/g也可以写成new RegExp('\d+', 'g')new RegExp(/\d+/, 'g'),表示至少一位的数字字符0~9,global模式。
去查 javascript 正则表达式规则 替换/\d+/g
你需要什么规则,即用什么规则。

数据量

如果你要操作的文本量很大,当然不适合直接在浏览器控制台这样写。
如果你需要把这个过程固化,提供一个输入,并输出到指定位置,浏览器控制台也只能帮你测试/验证语法。

增加要处理的数据量/将程序处理流程固化,到最后要调用的基础API不会变。
会变的只是其他节点。
浏览器控制台只是用于小数据量的文本处理+语法测试/猜想验证。

除了 Uint32Array 还有其他什么类似的类型可以达到类似的排序效果

有啊,而且还有好几种,见MDN TypedArray
按照单个变量所需字节数递增,依次有 Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, BigIntArray, BigUint64Array
在这里插入图片描述按照你的需求,不同情况下分别选择最适合的类型。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值