[ 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);
相关推荐
博客zhu虎康19 小时前
React Hooks 报错?一招解决useState问题
前端·javascript·react.js
灰海19 小时前
vue中通过heatmap.js实现热力图(多个热力点)热区展示(带鼠标移入弹窗)
前端·javascript·vue.js·heatmap·heatmapjs
王源骏19 小时前
LayaAir鼠标(手指)控制相机旋转,限制角度
前端
大虾写代码20 小时前
vue3+TS项目配置Eslint+prettier+husky语法校验
前端·vue·eslint
wordbaby20 小时前
用 useEffectEvent 做精准埋点:React analytics pageview 场景的最佳实践与原理剖析
前端·react.js
上单带刀不带妹20 小时前
在 ES6 中如何提取深度嵌套的对象中的指定属性
前端·ecmascript·es6
excel20 小时前
使用热力贴图和高斯函数生成山峰与等高线的 WebGL Shader 解析
前端
wyzqhhhh20 小时前
组件库打包工具选型(npm/pnpm/yarn)的区别和技术考量
前端·npm·node.js
码上暴富20 小时前
vue2迁移到vite[保姆级教程]
前端·javascript·vue.js
土了个豆子的21 小时前
04.事件中心模块
开发语言·前端·visualstudio·单例模式·c#