前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >无序数组判断内容相等

无序数组判断内容相等

作者头像
上山打老虎了
发布2022-06-15 09:01:13
1.4K0
发布2022-06-15 09:01:13
举报
文章被收录于专栏:Article

最近开发一个功能,使用 Mysql 存储的数据,数据源是 Elactic Search,每天凌晨获取一下当前某个项目的性能指标的平均值。

由于提供了 URL筛选的范围,所以对于查询条件出现了排列组合的方式,类似下面这样的。

代码语言:javascript
复制
const params = [{ path: 'a.com', filter: 0 }, { path: 'b.com', filter: 1 }]; // 查询条件

先是计算出全组合,这里有一个算法:

代码语言:javascript
复制
/*
  全组合算法
  输入 [a,b,c,d,e]
  输出 [Array(5), Array(10), Array(10), Array(5), Array(1)]
  展开后得
  ['A', 'B', 'C', 'D', 'E']
  ['AB', 'AC', 'BC', 'AD', 'BD', 'CD', 'AE', 'BE', 'CE', 'DE']
  ['ABC', 'ABD', 'ACD', 'BCD', 'ABE', 'ACE', 'BCE', 'ADE', 'BDE', 'CDE']
  ['ABCD', 'ABCE', 'ABDE', 'ACDE', 'BCDE']
  ['ABCDE']
 */
Helper.combination = (arr) => {
  const list = [];
  for (let i = 0; i < arr.length; i++) {
    list.push([]);
  }

  const l = Math.pow(2, arr.length) - 1;

  for (let i = 1; i <= l; i++) {
    const t = [];

    for (let s = i, k = 0; s > 0; s >>= 1, k++) {
      if ((s & 1) === 1) {
        t.push(arr[k]);
      }
    }

    list[t.length - 1].push([t]); // join 的分隔符可以自行约定
  }

  return list.flat(2); // 拍平
};

因为我的查询条件是一个对象数组,最小的查询单元也是一个对象,如果要把这个对象当成一个查询维度存储到数据库中,首先想到的是 Hash,我首先想到了用 MD5 hash 一下 JSON.strigify([{}])后的内容,然而在查询的时候却无法查询到。

此时我发现请求的参数中数组的内元素顺序会发生改变,虽然内容不变,但是顺序变换之后,Hash 的结果也因此发生改变,所以需要先调整数组的位置,形成一个“稳定的”结构后再 Hash 存储。

所以就转变为了字符串的比较,通过调整顺序,最终形成的字符串一定是一样的。

代码语言:javascript
复制
/* 字符串排序 */
const sort = (str) => {
  const strArr = str.split('');
  const sorted = strArr.sort((a, b) => a.localeCompare(b)); // 转换成字符串排序
  return sorted.join(); // 变成字符串用于 Hash
};

这里我通过 sort 方法来比较字符之前的顺序,从而达到调整位置的目的。其他同事有提到 charCodeAt 转变为数字,再排序形成字符串的形式,不过这种方式本质都是一样的,从乱序到有序的过程。

Finish!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年12月03日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档