[ Javascript 面试题 ]:提取对应的信息,并给其赋予一个颜色,保持幂等性

题目

有一不定长的数组,里面存有的元素是字符串的形式,每个字符串包含运营商与 IP 地址的信息(用 -分隔)。

我们希望每个运营商都有一个对应的颜色,即使每次重新运行,传入不同的数组,该颜色对应都不改变。

实现幂等性:相同的输入字符串总是产生相同的输出颜色。

输入

js 复制代码
let arr = [
    "电信-111.123.321.22",
    "移动-121.111.321.11",
    "联通-123.123.321.33",
    "ABC-133.123.321.44",
    "ABC-144.123.321.55",
];

输出

bash 复制代码
[
  {value:"电信-111.123.321.22",src:"电信",ip:"111.123.321.22",color:"#e5cfc5"},
  {value:"移动-121.111.321.11",src:"移动",ip:"121.111.321.11",color:"#99f5d8"},
  {value:"联通-123.123.321.33",src:"联通",ip:"123.123.321.33",color:"#aeefae"},
  {value:"ABC-133.123.321.44",src:"ABC",ip:"133.123.321.44",color:"#da838b"},
  {value:"ABC-144.123.321.55",src:"ABC",ip:"144.123.321.55",color:"#da838b"},
]

思路

  1. 先处理最简单的部分,将 ip 和 运营商 分割(使用 "".split() 函数)。

  2. 一开始我想着用 Map 来存储运营商与颜色的映射,但这样只要重新传入不同数组,颜色的对应就会改变,无法保证幂等性。

    js 复制代码
    let arr = [
      "电信-111.123.321.22",
      "移动-121.111.321.11",
      "联通-123.123.321.33",
      "ABC-133.123.321.44",
      "ABC-144.123.321.55",
    ];
    ​
    let map = new Map();
    ​
    // 此处逐个生成新颜色,简要编写非最终效果
    let color = 0;
    function colorGen() {
      color += 10;
      return "#"+color;
    }
    ​
    let ans = arr.map((value) => {
      let [key, ip] = value.split("-");
      let color = map.get(key);
    ​
      if (!color) {
        color = colorGen();
        map.set(key, color);
      }
    ​
      return {
        value,
        src: key,
        ip,
        color,
      };
    });
    ​
    console.log(ans);
  3. 正确的实现方法是哈希,获取一个值将其映射为颜色

    js 复制代码
    let arr = [
      "电信-111.123.321.22",
      "移动-121.111.321.11",
      "联通-123.123.321.33",
      "ABC-133.123.321.44",
      "ABC-144.123.321.55",
    ];
    
    // 经典DJB2哈希算法变种,生成一个哈希值
    function hash(str) {
      let hashValue = 5381; // 初始质数(常用哈希种子)
      for (let i = 0; i < str.length; i++)
        hashValue = (hashValue << 5) + hashValue + str.charCodeAt(i);
      return hashValue;
    }
    
    // 将哈希值映射为颜色,颜色的 RGB 每一个位置都有两个十六进制数
    function colorGen(key) {
      let hashValue = hash(key);
    
      let color = "#";
    
      for (let i = 0; i < 3; i++) {
        const value = (hashValue >> (i * 8)) & 0xff;   // 移位后取最右边 8 位
        const adjust = 0x80 + (value % 0x80);          // 限制在 128 到 255,避免过暗
        color += adjust.toString(16).padStart(2, '0'); // 避免数字不够两位
      }
    
      return color;
    }
    
    let ans = arr.map((value) => {
      let [key, ip] = value.split("-");
    
      return {
        value,
        src: key,
        ip,
        color: colorGen(key),
      };
    });
    
    console.log(ans);
相关推荐
一枚前端小能手1 分钟前
🎨 用户等不了3秒就跑了,你这时如何是好
前端
Eddy4 分钟前
什么时候应该用useCallback
前端
愿化为明月_随波逐流5 分钟前
关于uniapp开发安卓sdk的aar,用来控制pda的rfid的扫描
前端
探码科技6 分钟前
AI知识管理全面指南:助力企业高效协作与创新
前端
Eddy6 分钟前
react中什么时候应该用usecallback中代码优化
前端
Aurora01037 分钟前
树型结构,动态计算-实现表单合并【行、列】
javascript
Juchecar15 分钟前
Vue3 应用、组件概念详解 - 初学者完全指南
前端·vue.js
w_y_fan16 分钟前
双token机制:flutter_secure_storage 实现加密存储
前端·flutter
yvvvy18 分钟前
HTTP 从 0.9 到 3.0,一次穿越 30 年的网络进化之旅
前端·javascript
复苏季风42 分钟前
聊聊 ?? 运算符:一个懂得 "分寸" 的默认值高手
前端·javascript