tools.ts 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. import { _decorator, absMax, assetManager, Component, ImageAsset, instantiate, Node, Prefab, resources, SpriteFrame, Texture2D } from 'cc';
  2. import { gameManager } from './gameManager';
  3. import { config } from './config';
  4. import { toast } from './toast';
  5. import { dialog } from './dialog/dialog';
  6. const { ccclass, property } = _decorator;
  7. export class tools {
  8. public static showToast(text:string){
  9. if(gameManager.getTopLayer()==null){
  10. console.log("gameManager.topLayer -- null!");
  11. return;
  12. }
  13. resources.load(config.PREFAB_PATH.toast, Prefab, (err, prefab) => {
  14. if(err){
  15. console.log("addTopView -- err::",err);
  16. return;
  17. }
  18. let newNode:Node = instantiate(prefab);
  19. newNode.parent = gameManager.getTopLayer();
  20. newNode.getComponent(toast).showView(text);
  21. });
  22. }
  23. public static showDialog(text:string,call_yes=null,call_not=null){
  24. if(gameManager.getTopLayer()==null){
  25. console.log("gameManager.topLayer -- null!");
  26. return;
  27. }
  28. resources.load(config.PREFAB_PATH.dialog, Prefab, (err, prefab) => {
  29. if(err){
  30. console.log("addTopView -- err::",err);
  31. return;
  32. }
  33. let newNode:Node = instantiate(prefab);
  34. newNode.parent = gameManager.getTopLayer();
  35. newNode.getComponent(dialog).show(text,call_yes,call_not);
  36. });
  37. }
  38. public static showDialogOne(text:string,call_yes=null){
  39. if(gameManager.getTopLayer()==null){
  40. console.log("gameManager.topLayer -- null!");
  41. return;
  42. }
  43. resources.load(config.PREFAB_PATH.dialog, Prefab, (err, prefab) => {
  44. if(err){
  45. console.log("addTopView -- err::",err);
  46. return;
  47. }
  48. let newNode:Node = instantiate(prefab);
  49. newNode.parent = gameManager.getTopLayer();
  50. newNode.getComponent(dialog).showOne(text,call_yes);
  51. });
  52. }
  53. public static loadRemoteImg(url,call_back,id=null){
  54. assetManager.loadRemote<ImageAsset>(url, (err, imageAsset2)=>{
  55. if (!err && imageAsset2) {
  56. const texture = new Texture2D();
  57. texture.image = imageAsset2;
  58. let spFrame2 = new SpriteFrame();
  59. spFrame2.texture = texture;
  60. if(id!=null){
  61. call_back(spFrame2,id);
  62. }else{
  63. call_back(spFrame2);
  64. }
  65. }
  66. });
  67. }
  68. public static loadRemoteImgByCategoryid(categoryid:number,level:number,url,call_back,id=null){
  69. let map = gameManager.cache.get(`${level}_${categoryid}`)
  70. let isCache = false;
  71. if(map!=null&&map.size>0){
  72. if(map.get(url)){
  73. isCache =true;
  74. if(id!=null){
  75. call_back(map.get(url),id);
  76. }else{
  77. call_back(map.get(url));
  78. }
  79. }
  80. }
  81. if(!isCache){
  82. assetManager.loadRemote<ImageAsset>(url, (err, imageAsset2)=>{
  83. if (!err && imageAsset2) {
  84. const texture = new Texture2D();
  85. texture.image = imageAsset2;
  86. let spFrame2 = new SpriteFrame();
  87. spFrame2.texture = texture;
  88. if(id!=null){
  89. call_back(spFrame2,id);
  90. }else{
  91. call_back(spFrame2);
  92. }
  93. }
  94. });
  95. }
  96. }
  97. public static sortDoudizhuCards(cards, ascending = true) {
  98. const cardsCopy = cards.slice();
  99. return cardsCopy.sort((a, b) => {
  100. return ascending
  101. ? parseInt(a) - parseInt(b)
  102. : parseInt(b) - parseInt(a);
  103. });
  104. }
  105. // # check if move is a continuous sequence //是连续序列
  106. public static is_continuous_seq(move){
  107. var i = 0;
  108. while (i < move.length - 1) {
  109. if (parseInt(move[i+1]) - parseInt( move[i]) !== 1) {
  110. return false;
  111. }
  112. i++;
  113. }
  114. return true;
  115. }
  116. public static get_move_type(move){
  117. var moveSize = move.length;
  118. var moveDict = {};
  119. for (var i = 0; i < moveSize; i++) {
  120. moveDict[move[i]] = (moveDict[move[i]] || 0) + 1;
  121. }
  122. if (moveSize === 0) {
  123. return {'type': config.TYPE_0_PASS};
  124. }
  125. if (moveSize === 1) {
  126. return {'type': config.TYPE_1_SINGLE, 'rank': move[0]};
  127. }
  128. if (moveSize === 2) {
  129. if (move[0] === move[1]) {
  130. return {'type': config.TYPE_2_PAIR, 'rank': move[0]};
  131. } else if (move.toString() === [20, 30].toString()) { // Kings
  132. return {'type': config.TYPE_5_KING_BOMB};
  133. } else {
  134. return {'type': config.TYPE_15_WRONG};
  135. }
  136. }
  137. if (moveSize === 3) {
  138. if (Object.keys(moveDict).length === 1) {
  139. return {'type': config.TYPE_3_TRIPLE, 'rank': move[0]};
  140. } else {
  141. return {'type': config.TYPE_15_WRONG};
  142. }
  143. }
  144. if (moveSize === 4) {
  145. if (Object.keys(moveDict).length === 1) {
  146. return {'type': config.TYPE_4_BOMB, 'rank': move[0]};
  147. } else if (Object.keys(moveDict).length === 2) {
  148. if (move[0] === move[1] && move[1] === move[2] || move[1] === move[2] && move[2] === move[3]) {
  149. return {'type': config.TYPE_6_3_1, 'rank': move[1]};
  150. } else {
  151. return {'type': config.TYPE_15_WRONG};
  152. }
  153. } else {
  154. return {'type': config.TYPE_15_WRONG};
  155. }
  156. }
  157. if (tools.is_continuous_seq(move)) {
  158. return {'type': config.TYPE_8_SERIAL_SINGLE, 'rank': move[0], 'len': move.length};
  159. }
  160. if (moveSize === 5) {
  161. if (Object.keys(moveDict).length === 2) {
  162. return {'type': config.TYPE_7_3_2, 'rank': move[2]};
  163. } else {
  164. return {'type': config.TYPE_15_WRONG};
  165. }
  166. }
  167. var countDict = {};
  168. for (var key in moveDict) {
  169. if (countDict[moveDict[key]]) {
  170. countDict[moveDict[key]] += 1;
  171. } else {
  172. countDict[moveDict[key]] = 1;
  173. }
  174. }
  175. if (moveSize === 6) {
  176. if ((Object.keys(moveDict).length === 2 || Object.keys(moveDict).length === 3) && countDict[4] === 1 && (countDict[2] === 1 || countDict[1] === 2)) {
  177. return {'type': config.TYPE_13_4_2, 'rank': move[2]};
  178. }
  179. }
  180. if (moveSize === 8 && (((Object.keys(moveDict).length === 3 || Object.keys(moveDict).length === 2) && (countDict[4] === 1 && countDict[2] === 2)) || countDict[4] === 2)) {
  181. return {'type': config.TYPE_14_4_22, 'rank': Math.max.apply(null, Object.keys(moveDict).filter(function(key) { return moveDict[key] === 4; }))};
  182. }
  183. var mdKeys = Object.keys(moveDict).sort();
  184. if (Object.keys(moveDict).length === countDict[2] && tools.is_continuous_seq(mdKeys)) {
  185. return {'type': config.TYPE_9_SERIAL_PAIR, 'rank': parseInt(mdKeys[0]), 'len': mdKeys.length};
  186. }
  187. if (Object.keys(moveDict).length === countDict[3] && tools.is_continuous_seq(mdKeys) ) {
  188. return {'type': config.TYPE_10_SERIAL_TRIPLE, 'rank': parseInt(mdKeys[0]), 'len': mdKeys.length};
  189. }
  190. if (countDict[3] >= config.MIN_TRIPLES) {
  191. var serial3 = [];
  192. var single = [];
  193. var pair = [];
  194. for (var key in moveDict) {
  195. if (moveDict[key] === 3) {
  196. serial3.push(parseInt(key));
  197. } else if (moveDict[key] === 1) {
  198. single.push(parseInt(key));
  199. } else if (moveDict[key] === 2) {
  200. pair.push(parseInt(key));
  201. } else {
  202. return {'type': config.TYPE_15_WRONG};
  203. }
  204. }
  205. serial3.sort((a,b)=>{return a - b});
  206. let is_continuous_seq = tools.is_continuous_seq(serial3)
  207. if (is_continuous_seq) {
  208. if (serial3.length === single.length + pair.length * 2) {
  209. return {'type': config.TYPE_11_SERIAL_3_1, 'rank': serial3[0], 'len': serial3.length};
  210. }
  211. if (serial3.length === pair.length && Object.keys(moveDict).length === serial3.length * 2) {
  212. return {'type': config.TYPE_12_SERIAL_3_2, 'rank': serial3[0], 'len': serial3.length};
  213. }
  214. }
  215. if (serial3.length === 4) {
  216. if (tools.is_continuous_seq(serial3.slice(1))) {
  217. return {'type': config.TYPE_11_SERIAL_3_1, 'rank': serial3[1], 'len': serial3.length - 1};
  218. }
  219. if (tools.is_continuous_seq(serial3.slice(0, -1))) {
  220. return {'type': config.TYPE_11_SERIAL_3_1, 'rank': serial3[0], 'len': serial3.length - 1};
  221. }
  222. }
  223. }
  224. return {'type': config.TYPE_15_WRONG};
  225. }
  226. //# return the type of the move
  227. // public static get_move_type(move){
  228. // var move_size = move.length;
  229. // var move_dict = {};
  230. // for (var i = 0; i < move.length; i++) {
  231. // var item = move[i];
  232. // move_dict[item] = (move_dict[item] || 0) + 1;
  233. // }
  234. // if (move_size === 0) {
  235. // return { 'type': config.TYPE_0_PASS };
  236. // }
  237. // if (move_size === 1) {
  238. // return { 'type': config.TYPE_1_SINGLE, 'rank': move[0] };
  239. // }
  240. // if (move_size === 2) {
  241. // if (move[0] === move[1]) {
  242. // return { 'type': config.TYPE_2_PAIR, 'rank': move[0] };
  243. // } else if (move.toString() === [20, 30].toString()) { // Kings
  244. // return { 'type': config.TYPE_5_KING_BOMB };
  245. // } else {
  246. // return { 'type': config.TYPE_15_WRONG };
  247. // }
  248. // }
  249. // if (move_size === 3) {
  250. // if (Object.keys(move_dict).length === 1) {
  251. // return { 'type': config.TYPE_3_TRIPLE, 'rank': move[0] };
  252. // } else {
  253. // return { 'type': config.TYPE_15_WRONG };
  254. // }
  255. // }
  256. // if (move_size === 4) {
  257. // if (Object.keys(move_dict).length === 1) {
  258. // return { 'type': config.TYPE_4_BOMB, 'rank': move[0] };
  259. // } else if (Object.keys(move_dict).length === 2) {
  260. // if (move[0] === move[1] && move[1] === move[2] || move[1] === move[2] && move[2] === move[3]) {
  261. // return { 'type': config.TYPE_6_3_1, 'rank': move[1] };
  262. // } else {
  263. // return { 'type': config.TYPE_15_WRONG };
  264. // }
  265. // } else {
  266. // return { 'type': config.TYPE_15_WRONG };
  267. // }
  268. // }
  269. // if (tools.is_continuous_seq(move)) {
  270. // return { 'type': config.TYPE_8_SERIAL_SINGLE, 'rank': move[0], 'len': move.length };
  271. // }
  272. // if (move_size === 5) {
  273. // if (Object.keys(move_dict).length === 2) {
  274. // return { 'type': config.TYPE_7_3_2, 'rank': move[2] };
  275. // } else {
  276. // return { 'type': config.TYPE_15_WRONG };
  277. // }
  278. // }
  279. // var count_dict = {};
  280. // for (var c in move_dict) {
  281. // var n = move_dict[c];
  282. // count_dict[n] = (count_dict[n] || 0) + 1;
  283. // }
  284. // if (move_size === 6) {
  285. // if ((Object.keys(move_dict).length === 2 || Object.keys(move_dict).length === 3) && count_dict[4] === 1 && (count_dict[2] === 1 || count_dict[1] === 2)) {
  286. // return { 'type': config.TYPE_13_4_2, 'rank': move[2] };
  287. // }
  288. // }
  289. // if (move_size === 8 && ((Object.keys(move_dict).length === 3 || Object.keys(move_dict).length === 2) && (count_dict[4] === 1 && count_dict[2] === 2) || count_dict[4] === 2)) {
  290. // return { 'type': config.TYPE_14_4_22, 'rank': Math.max.apply(null, Object.keys(move_dict).filter(function (c) { return move_dict[c] === 4; })) };
  291. // }
  292. // var mdkeys = Object.keys(move_dict).sort();
  293. // if (Object.keys(move_dict).length === count_dict[2] && tools.is_continuous_seq(mdkeys)) {
  294. // return { 'type': config.TYPE_9_SERIAL_PAIR, 'rank': mdkeys[0], 'len': mdkeys.length };
  295. // }
  296. // if (Object.keys(move_dict).length === count_dict[3] && tools.is_continuous_seq(mdkeys)) {
  297. // return { 'type': config.TYPE_10_SERIAL_TRIPLE, 'rank': mdkeys[0], 'len': mdkeys.length };
  298. // }
  299. // if (count_dict[3] >= config.MIN_TRIPLES) {
  300. // var serial_3 = [];
  301. // var single = [];
  302. // var pair = [];
  303. // for (var k in move_dict) {
  304. // var v = move_dict[k];
  305. // if (v === 3) {
  306. // serial_3.push(k);
  307. // } else if (v === 1) {
  308. // single.push(k);
  309. // } else if (v === 2) {
  310. // pair.push(k);
  311. // } else {
  312. // return { 'type': config.TYPE_15_WRONG };
  313. // }
  314. // }
  315. // serial_3.sort();
  316. // if (tools.is_continuous_seq(serial_3)) {
  317. // if (serial_3.length === single.length + pair.length * 2) {
  318. // return { 'type': config.TYPE_11_SERIAL_3_1, 'rank': serial_3[0], 'len': serial_3.length };
  319. // }
  320. // if (serial_3.length === pair.length && Object.keys(move_dict).length === serial_3.length * 2) {
  321. // return { 'type': config.TYPE_12_SERIAL_3_2, 'rank': serial_3[0], 'len': serial_3.length };
  322. // }
  323. // }
  324. // if (serial_3.length === 4) {
  325. // if (tools.is_continuous_seq(serial_3.slice(1))) {
  326. // return { 'type': config.TYPE_11_SERIAL_3_1, 'rank': serial_3[1], 'len': serial_3.length - 1 };
  327. // }
  328. // if (tools.is_continuous_seq(serial_3.slice(0, -1))) {
  329. // return { 'type': config.TYPE_11_SERIAL_3_1, 'rank': serial_3[0], 'len': serial_3.length - 1 };
  330. // }
  331. // }
  332. // }
  333. // return { 'type': config. TYPE_15_WRONG };
  334. // }
  335. public static common_handle(moves, rival_move){
  336. var new_moves = [];
  337. for (let index = 0; index < moves.length; index++) {
  338. const move = moves[index];
  339. if (parseInt(move[0]) > parseInt(rival_move[0])) {
  340. new_moves.push(move);
  341. }
  342. }
  343. return [new_moves];
  344. }
  345. public static filter_type_1_single(moves, rival_move){
  346. return tools.common_handle(moves, rival_move)
  347. }
  348. public static filter_type_2_pair(moves, rival_move){
  349. return tools.common_handle(moves, rival_move)
  350. }
  351. public static filter_type_3_triple(moves, rival_move){
  352. return tools.common_handle(moves, rival_move)
  353. }
  354. public static filter_type_4_bomb(moves, rival_move){
  355. return tools.common_handle(moves, rival_move)
  356. }
  357. //# No need to filter for type_5_king_bomb
  358. public static filter_type_6_3_1(moves, rival_move){
  359. rival_move.sort();
  360. var rival_rank = rival_move[1];
  361. var new_moves = [];
  362. moves.forEach(function(move) {
  363. move.sort();
  364. var my_rank = move[1];
  365. if (parseInt(my_rank) > parseInt(rival_rank) ) {
  366. new_moves.push(move);
  367. }
  368. });
  369. return new_moves;
  370. }
  371. public static filter_type_7_3_2(moves, rival_move){
  372. rival_move.sort()
  373. let rival_rank = rival_move[2]
  374. let new_moves = []
  375. for (let index = 0; index < moves.length; index++) {
  376. const move = moves[index];
  377. move.sort()
  378. let my_rank = move[2]
  379. if(parseInt(my_rank) > parseInt(rival_rank))
  380. new_moves.push(move)
  381. }
  382. return new_moves
  383. }
  384. public static filter_type_8_serial_single(moves, rival_move){
  385. return tools.common_handle(moves, rival_move)
  386. }
  387. public static filter_type_9_serial_pair(moves, rival_move){
  388. return tools.common_handle(moves, rival_move)
  389. }
  390. public static filter_type_10_serial_triple(moves, rival_move){
  391. return tools.common_handle(moves, rival_move)
  392. }
  393. public static filter_type_11_serial_3_1(moves, rival_move){
  394. let rival = {};
  395. for (let i = 0; i < rival_move.length; i++) {
  396. if (!rival[rival_move[i]]) {
  397. rival[rival_move[i]] = 1;
  398. } else {
  399. rival[rival_move[i]]++;
  400. }
  401. }
  402. let rival_rank = Object.keys(rival).reduce((a, b) => rival[a] > rival[b] ? a : b);
  403. let new_moves = [];
  404. for (let i = 0; i < moves.length; i++) {
  405. let mymove = {};
  406. for (let j = 0; j < moves[i].length; j++) {
  407. if (!mymove[moves[i][j]]) {
  408. mymove[moves[i][j]] = 1;
  409. } else {
  410. mymove[moves[i][j]]++;
  411. }
  412. }
  413. let my_rank = Object.keys(mymove).reduce((a, b) => mymove[a] > mymove[b] ? a : b);
  414. if (my_rank > rival_rank) {
  415. new_moves.push(moves[i]);
  416. }
  417. }
  418. return new_moves;
  419. }
  420. public static filter_type_12_serial_3_2(moves, rival_move){
  421. let rival = {};
  422. for (let i = 0; i < rival_move.length; i++) {
  423. if (!rival[rival_move[i]]) {
  424. rival[rival_move[i]] = 1;
  425. } else {
  426. rival[rival_move[i]]++;
  427. }
  428. }
  429. let rival_rank = Object.keys(rival).reduce((a, b) => rival[a] > rival[b] ? a : b);
  430. let new_moves = [];
  431. for (let i = 0; i < moves.length; i++) {
  432. let mymove = {};
  433. for (let j = 0; j < moves[i].length; j++) {
  434. if (!mymove[moves[i][j]]) {
  435. mymove[moves[i][j]] = 1;
  436. } else {
  437. mymove[moves[i][j]]++;
  438. }
  439. }
  440. let my_rank = Object.keys(mymove).reduce((a, b) => mymove[a] > mymove[b] ? a : b);
  441. if (my_rank > rival_rank) {
  442. new_moves.push(moves[i]);
  443. }
  444. }
  445. return new_moves;
  446. }
  447. public static filter_type_13_4_2(moves, rival_move){
  448. rival_move.sort()
  449. let rival_rank = rival_move[2]
  450. let new_moves = []
  451. for (let index = 0; index < moves.length; index++) {
  452. const move = moves[index];
  453. move.sort()
  454. let my_rank = move[2]
  455. if(parseInt(my_rank) > parseInt(rival_rank))
  456. new_moves.push(move)
  457. }
  458. return new_moves
  459. }
  460. public static filter_type_14_4_22(moves, rival_move){
  461. var rival = {};
  462. for (var i = 0; i < rival_move.length; i++) {
  463. rival[rival_move[i]] = rival[rival_move[i]] ? rival[rival_move[i]] + 1 : 1;
  464. }
  465. var rivalRank = 0;
  466. var myRank = 0;
  467. for (var key in rival) {
  468. if (rival.hasOwnProperty(key) && rival[key] === 4) {
  469. rivalRank = parseInt(key);
  470. break;
  471. }
  472. }
  473. var newMoves = [];
  474. for (var j = 0; j < moves.length; j++) {
  475. var myMove = {};
  476. for (var k = 0; k < moves[j].length; k++) {
  477. myMove[moves[j][k]] = myMove[moves[j][k]] ? myMove[moves[j][k]] + 1 : 1;
  478. }
  479. for (var key in myMove) {
  480. if (myMove.hasOwnProperty(key) && myMove[key] === 4) {
  481. myRank = parseInt(key);
  482. break;
  483. }
  484. }
  485. if (myRank > rivalRank) {
  486. newMoves.push(moves[j]);
  487. }
  488. }
  489. return newMoves;
  490. }
  491. public static getCardMin(list:any[]):string{
  492. list.sort((a,b)=>{
  493. return parseInt(a[0] )- parseInt(b[0])
  494. })
  495. for (let index = 0; index < list.length; index++) {
  496. const element = list[index];
  497. if(element!=null&&element!=undefined&&element.length>0){
  498. return element[0]
  499. }
  500. }
  501. return list[0]
  502. }
  503. public static isArraysEqual(arr1, arr2) {
  504. if (arr1.length !== arr2.length) {
  505. return false;
  506. }
  507. for (var i = 0; i < arr1.length; i++) {
  508. if (arr1[i] !== arr2[i]) {
  509. return false;
  510. }
  511. }
  512. return true;
  513. }
  514. public static isEqualArray(arr1, arr2) {
  515. if (arr1.length !== arr2.length) {
  516. return false;
  517. }
  518. var isEqual = true;
  519. arr1.forEach(function(element) {
  520. if (!arr2.includes(element)) {
  521. isEqual = false;
  522. }
  523. });
  524. return isEqual;
  525. }
  526. public static delete_element(list:[],element)
  527. {
  528. let new_list = []
  529. let is_delete = false;
  530. for (let index = 0; index < list.length; index++) {
  531. const item = list[index];
  532. if(element===item&&!is_delete){
  533. is_delete = true;
  534. }else{
  535. new_list.push(item)
  536. }
  537. }
  538. return new_list;
  539. }
  540. public static delete_card(original_cards,sub_cards){
  541. let index = 0;
  542. let list = original_cards
  543. while(index<sub_cards.length){
  544. list = tools.delete_element(list,sub_cards[index])
  545. index++;
  546. }
  547. return list;
  548. }
  549. public static get_list_element(list:any[],i:number){
  550. let new_list = []
  551. new_list.push(list[i])
  552. for (let index = 0; index < list.length; index++) {
  553. const element = list[index];
  554. if(index!=i){
  555. new_list.push(element)
  556. }
  557. }
  558. return new_list;
  559. }
  560. public static sortByPercentage(arr) {
  561. // 计算每个元素的占比
  562. const counts = {};
  563. arr.forEach(element => {
  564. counts[element] = (counts[element] || 0) + 1;
  565. });
  566. // 排序数组
  567. const sortedArr = arr.sort((a, b) => {
  568. return counts[b] / arr.length - counts[a] / arr.length;
  569. });
  570. // 返回排序后的元素
  571. return sortedArr;
  572. }
  573. }