首页 > 编程语言 >JavaScript 编程语言【 数据类型】过滤|排序|映射|迭代

JavaScript 编程语言【 数据类型】过滤|排序|映射|迭代

时间:2024-07-01 18:01:35浏览次数:3  
标签:arr 迭代 编程语言 JavaScript 数据类型 alert let 数组 name

文章目录

      • 将 border-left-width 转换成 borderLeftWidth
      • 过滤范围
      • 原位(in place)过滤范围
      • 降序排列
      • 复制和排序数组
      • 创建一个可扩展的 calculator
      • 映射到 names
      • 映射到对象
      • 按年龄对用户排序
      • 随机排列数组
      • 获取平均年龄
      • 数组去重
      • 从数组创建键(值)对象
  • Iterable object(可迭代对象)
    • Symbol.iterator
    • 字符串是可迭代的
    • 显式调用迭代器
    • 可迭代(iterable)和类数组(array-like)
    • Array.from
    • 总结

✅任务

将 border-left-width 转换成 borderLeftWidth

重要程度5️⃣

编写函数 camelize(str) 将诸如 “my-short-string” 之类的由短划线分隔的单词变成骆驼式的 “myShortString”。

即:删除所有短横线,并将短横线后的每一个单词的首字母变为大写。

示例:

camelize("background-color") == 'backgroundColor';
camelize("list-style-image") == 'listStyleImage';
camelize("-webkit-transition") == 'WebkitTransition';

提示:使用 split 将字符串拆分成数组,对其进行转换之后再 join 回来。

打开带有测试的沙箱。

解决方案

function camelize(str) {
return str
 .split('-') // splits 'my-long-word' into array ['my', 'long', 'word']
 .map(
   // capitalizes first letters of all array items except the first one
   // converts ['my', 'long', 'word'] into ['my', 'Long', 'Word']
   (word, index) => index == 0 ? word : word[0].toUpperCase() + word.slice(1)
 )
 .join(''); // joins ['my', 'Long', 'Word'] into 'myLongWord'
}

使用沙箱的测试功能打开解决方案。

过滤范围

重要程度4️⃣

写一个函数 filterRange(arr, a, b),该函数获取一个数组 arr,在其中查找数值大于或等于 a,且小于或等于 b 的元素,并将结果以数组的形式返回。

该函数不应该修改原数组。它应该返回新的数组。

例如:

let arr = [5, 3, 8, 1];

let filtered = filterRange(arr, 1, 4);

alert( filtered ); // 3,1(匹配值)

alert( arr ); // 5,3,8,1(未修改)

打开带有测试的沙箱。

解决方案

function filterRange(arr, a, b) {
// 在表达式周围添加了括号,以提高可读性
return arr.filter(item => (a <= item && item <= b));
}

let arr = [5, 3, 8, 1];

let filtered = filterRange(arr, 1, 4);

alert( filtered ); // 3,1(匹配的值)

alert( arr ); // 5,3,8,1(未经改动的数组中的值)

使用沙箱的测试功能打开解决方案。

原位(in place)过滤范围

重要程度4️⃣

写一个函数 filterRangeInPlace(arr, a, b),该函数获取一个数组 arr,并删除其中介于 ab 区间以外的所有值。检查:a ≤ arr[i] ≤ b

该函数应该只修改数组。它不应该返回任何东西。

例如:

let arr = [5, 3, 8, 1];

filterRangeInPlace(arr, 1, 4); // 删除了范围在 1 到 4 之外的所有值

alert( arr ); // [3, 1]

打开带有测试的沙箱。

解决方案

function filterRangeInPlace(arr, a, b) {

for (let i = 0; i < arr.length; i++) {
 let val = arr[i];

 // 如果超出范围,则删除
 if (val < a || val > b) {
   arr.splice(i, 1);
   i--;
 }
}

}

let arr = [5, 3, 8, 1];

filterRangeInPlace(arr, 1, 4); // 删除 1 到 4 范围之外的值

alert( arr ); // [3, 1]

使用沙箱的测试功能打开解决方案。

降序排列

重要程度4️⃣

let arr = [5, 2, 1, -10, 8];

// ……你的代码以降序对其进行排序

alert( arr ); // 8, 5, 2, 1, -10

解决方案

let arr = [5, 2, 1, -10, 8];

arr.sort((a, b) => b - a);

alert( arr );

复制和排序数组

重要程度5️⃣

我们有一个字符串数组 arr。我们希望有一个排序过的副本,但保持 arr 不变。

创建一个函数 copySorted(arr) 返回这样一个副本。

let arr = ["HTML", "JavaScript", "CSS"];

let sorted = copySorted(arr);

alert( sorted ); // CSS, HTML, JavaScript
alert( arr ); // HTML, JavaScript, CSS (no changes)

解决方案

我们可以使用 slice() 来创建一个副本并对其进行排序:

function copySorted(arr) {
return arr.slice().sort();
}

let arr = ["HTML", "JavaScript", "CSS"];

let sorted = copySorted(arr);

alert( sorted );
alert( arr );

创建一个可扩展的 calculator

重要程度5️⃣

创建一个构造函数 Calculator,以创建“可扩展”的 calculator 对象。

该任务由两部分组成。

  1. 首先,实现 calculate(str) 方法,该方法接受像 "1 + 2" 这样格式为“数字 运算符 数字”(以空格分隔)的字符串,并返回结果。该方法需要能够理解加号 + 和减号 -

    用法示例:

    let calc = new Calculator;
    
    alert( calc.calculate("3 + 7") ); // 10
    
  2. 然后添加方法 addMethod(name, func),该方法教 calculator 进行新操作。它需要运算符 name 和实现它的双参数函数 func(a,b)

    例如,我们添加乘法 *,除法 / 和求幂 **

    let powerCalc = new Calculator;
    powerCalc.addMethod("*", (a, b) => a * b);
    powerCalc.addMethod("/", (a, b) => a / b);
    powerCalc.addMethod("**", (a, b) => a ** b);
    
    let result = powerCalc.calculate("2 ** 3");
    alert( result ); // 8
    
  • 此任务中没有括号或复杂的表达式。
  • 数字和运算符之间只有一个空格。
  • 你可以自行选择是否添加错误处理功能。

打开带有测试的沙箱。

解决方案

  • 请注意方法的存储方式。它们只是被添加到 this.methods 属性中。
  • 所有检测和数字转换都通过 calculate 方法完成。将来可能会扩展它以支持更复杂的表达式。
function Calculator() {

  this.methods = {
    "-": (a, b) => a - b,
    "+": (a, b) => a + b
  };

  this.calculate = function(str) {

    let split = str.split(' '),
      a = +split[0],
      op = split[1],
      b = +split[2];

    if (!this.methods[op] || isNaN(a) || isNaN(b)) {
      return NaN;
    }

    return this.methods[op](a, b);
  };

  this.addMethod = function(name, func) {
    this.methods[name] = func;
  };
}

使用沙箱的测试功能打开解决方案。

映射到 names

重要程度5️⃣

你有一个 user 对象数组,每个对象都有 user.name。编写将其转换为 names 数组的代码。

例如:

let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };

let users = [ john, pete, mary ];

let names = /* ... your code */

alert( names ); // John, Pete, Mary

解决方案

let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };

let users = [ john, pete, mary ];

let names = users.map(item => item.name);

alert( names ); // John, Pete, Mary

映射到对象

重要程度5️⃣

你有一个 user 对象数组,每个对象都有 namesurnameid

编写代码以该数组为基础,创建另一个具有 idfullName 的对象数组,其中 fullNamenamesurname 生成。

例如:

let john = { name: "John", surname: "Smith", id: 1 };
let pete = { name: "Pete", surname: "Hunt", id: 2 };
let mary = { name: "Mary", surname: "Key", id: 3 };

let users = [ john, pete, mary ];

let usersMapped = /* ... your code ... */

/*
usersMapped = [
  { fullName: "John Smith", id: 1 },
  { fullName: "Pete Hunt", id: 2 },
  { fullName: "Mary Key", id: 3 }
]
*/

alert( usersMapped[0].id ) // 1
alert( usersMapped[0].fullName ) // John Smith

所以,实际上你需要将一个对象数组映射到另一个对象数组。在这儿尝试使用箭头函数 => 来编写。

解决方案

let john = { name: "John", surname: "Smith", id: 1 };
let pete = { name: "Pete", surname: "Hunt", id: 2 };
let mary = { name: "Mary", surname: "Key", id: 3 };

let users = [ john, pete, mary ];

let usersMapped = users.map(user => ({
fullName: `${user.name} ${user.surname}`,
id: user.id
}));

/*
usersMapped = [
{ fullName: "John Smith", id: 1 },
{ fullName: "Pete Hunt", id: 2 },
{ fullName: "Mary Key", id: 3 }
]
*/

alert( usersMapped[0].id ); // 1
alert( usersMapped[0].fullName ); // John Smith

请注意,在箭头函数中,我们需要使用额外的括号。

我们不能这样写:

let usersMapped = users.map(user => {
fullName: `${user.name} ${user.surname}`,
id: user.id
});

我们记得,有两种箭头函数的写法:直接返回值 value => expr 和带主体的 value => {...}

JavaScript 在这里会把 { 视为函数体的开始,而不是对象的开始。解决方法是将它们包装在普通括号 () 中:

let usersMapped = users.map(user => ({
fullName: `${user.name} ${user.surname}`,
id: user.id
}));

这样就可以了。

按年龄对用户排序

重要程度5️⃣

编写函数 sortByAge(users) 获得对象数组的 age 属性,并根据 age 对这些对象数组进行排序。

例如:

let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };

let arr = [ pete, john, mary ];

sortByAge(arr);

// now: [john, mary, pete]
alert(arr[0].name); // John
alert(arr[1].name); // Mary
alert(arr[2].name); // Pete

解决方案

function sortByAge(arr) {
arr.sort((a, b) => a.age - b.age);
}

let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 28 };

let arr = [ pete, john, mary ];

sortByAge(arr);

// 排序后的数组为:[john, mary, pete]
alert(arr[0].name); // John
alert(arr[1].name); // Mary
alert(arr[2].name); // Pete

译注:解决方案的代码还可以更短一些

function sortByAge(arr) {
arr.sort((a, b) => a.age - b.age);
}

因为 sort() 方法的语法为 arr.sort([compareFunction]),如果没有指明 compareFunction,那么元素会被按照转换为的字符串的诸个字符的 Unicode 编码进行排序,如果指明了 compareFunction,那么数组会按照调用该函数的返回值排序。即 ab 是两个将要被比较的元素:

  • 如果 compareFunction(a, b) 小于 0,那么 a 会被排列到 b 之前;
  • 如果 compareFunction(a, b) 等于 0,那么 ab 的相对位置不变。备注:ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
  • 如果 compareFunction(a, b) 大于 0,那么 b 会被排列到 a 之前。

因此,升序排列的函数可以简写为:(a, b) => a.age - b.age

随机排列数组

重要程度3️⃣

编写函数 shuffle(array) 来随机排列数组的元素。

多次运行 shuffle 可能导致元素顺序的不同。例如:

let arr = [1, 2, 3];

shuffle(arr);
// arr = [3, 2, 1]

shuffle(arr);
// arr = [2, 1, 3]

shuffle(arr);
// arr = [3, 1, 2]
// ...

所有元素顺序应该具有相等的概率。例如,可以将 [1,2,3] 重新排序为 [1,2,3][1,3,2][3,1,2] 等,每种情况的概率相等。

解决方案

简单的解决方案可以是:

function shuffle(array) {
array.sort(() => Math.random() - 0.5);
}

let arr = [1, 2, 3];
shuffle(arr);
alert(arr);

这样是可以的,因为 Math.random() - 0.5 是一个可能是正数或负数的随机数,因此排序函数会随机地对数组中的元素进行重新排序。

但是,由于排序函数并非旨在以这种方式使用,因此并非所有的排列都具有相同的概率。

例如,请考虑下面的代码。它运行 100 万次 shuffle 并计算所有可能结果的出现次数:

function shuffle(array) {
array.sort(() => Math.random() - 0.5);
}

// 所有可能排列的出现次数
let count = {
'123': 0,
'132': 0,
'213': 0,
'231': 0,
'321': 0,
'312': 0
};

for (let i = 0; i < 1000000; i++) {
let array = [1, 2, 3];
shuffle(array);
count[array.join('')]++;
}

// 显示所有可能排列的出现次数
for (let key in count) {
alert(`${key}: ${count[key]}`);
}

示例结果(取决于 Javascript 引擎):

123: 250706
132: 124425
213: 249618
231: 124880
312: 125148
321: 125223

我们可以清楚地看到这种倾斜:123213 的出现频率比其他情况高得多。

使用不同的 JavaScript 引擎运行这个示例代码得到的结果可能会有所不同,但是我们已经可以看到这种方法是不可靠的。

为什么它不起作用?一般来说,sort 是一个“黑匣子”:我们将一个数组和一个比较函数放入其中,并期望其对数组进行排序。但是由于比较的完全随机性,这个黑匣子疯了,它发疯地确切程度取决于引擎中的具体实现方法。

还有其他很好的方法可以完成这项任务。例如,有一个很棒的算法叫作 Fisher-Yates shuffle。其思路是:逆向遍历数组,并将每个元素与其前面的随机的一个元素互换位置:

function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
 let j = Math.floor(Math.random() * (i + 1)); // 从 0 到 i 的随机索引

 // 交换元素 array[i] 和 array[j]
 // 我们使用“解构分配(destructuring assignment)”语法来实现它
 // 你将在后面的章节中找到有关该语法的更多详细信息
 // 可以写成:
 // let t = array[i]; array[i] = array[j]; array[j] = t
 [array[i], array[j]] = [array[j], array[i]];
}
}

让我们以相同的方式测试一下:

function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
 let j = Math.floor(Math.random() * (i + 1));
 [array[i], array[j]] = [array[j], array[i]];
}
}

// 所有可能排列的出现次数
let count = {
'123': 0,
'132': 0,
'213': 0,
'231': 0,
'321': 0,
'312': 0
};

for (let i = 0; i < 1000000; i++) {
let array = [1, 2, 3];
shuffle(array);
count[array.join('')]++;
}

// 显示所有可能排列的出现次数
for (let key in count) {
alert(`${key}: ${count[key]}`);
}

示例输出:

123: 166693
132: 166647
213: 166628
231: 167517
312: 166199
321: 166316

现在看起来不错:所有排列都以相同的概率出现。

另外,在性能方面,Fisher — Yates 算法要好得多,没有“排序”开销。

获取平均年龄

重要程度4️⃣

编写 getAverageAge(users) 函数,该函数获取一个具有 age 属性的对象数组,并返回平均年龄。

平均值的计算公式是 (age1 + age2 + ... + ageN) / N

例如:

let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 29 };

let arr = [ john, pete, mary ];

alert( getAverageAge(arr) ); // (25 + 30 + 29) / 3 = 28

解决方案

function getAverageAge(users) {
return users.reduce((prev, user) => prev + user.age, 0) / users.length;
}

let john = { name: "John", age: 25 };
let pete = { name: "Pete", age: 30 };
let mary = { name: "Mary", age: 29 };

let arr = [ john, pete, mary ];

alert( getAverageAge(arr) ); // 28

数组去重

重要程度4️⃣

arr 是一个数组。

创建一个函数 unique(arr),返回去除重复元素后的数组 arr

例如:

function unique(arr) {
  /* your code */
}

let strings = ["Hare", "Krishna", "Hare", "Krishna",
  "Krishna", "Krishna", "Hare", "Hare", ":-O"
];

alert( unique(strings) ); // Hare, Krishna, :-O

打开带有测试的沙箱。

解决方案

让我们先遍历数字:

  • 对于每个元素,我们将检查结果数组是否已经有该元素。
  • 如果有,则忽略,否则将其添加到结果中。
function unique(arr) {
  let result = [];

  for (let str of arr) {
    if (!result.includes(str)) {
      result.push(str);
    }
  }

  return result;
}

let strings = ["Hare", "Krishna", "Hare", "Krishna",
  "Krishna", "Krishna", "Hare", "Hare", ":-O"
];

alert( unique(strings) ); // Hare, Krishna, :-O

代码有效,但其中存在潜在的性能问题。

方法 result.includes(str) 在内部遍历数组 result,并将每个元素与 str 进行比较以找到匹配项。

所以如果 result 中有 100 个元素,并且没有任何一项与 str 匹配,那么它将遍历整个 result 并进行 100 次比较。如果 result 很大,比如 10000,那么就会有 10000 次的比较。

这本身并不是问题,因为 JavaScript 引擎速度非常快,所以遍历一个有 10000 个元素的数组只需要几微秒。

但是我们在 for循环中对 arr 的每个元素都进行了一次检测。

因此,如果 arr.length10000,我们会有 10000 * 10000 = 1 亿次的比较。那真的太多了。

所以该解决方案仅适用于小型数组。

进一步,在后面的 【Map and Set(映射和集合)】一章中,我们将看到如何对该方法进行优化。

使用沙箱的测试功能打开解决方案。

从数组创建键(值)对象

重要程度4️⃣

假设我们收到了一个用户数组,形式为:{id:..., name:..., age:... }

创建一个函数 groupById(arr) 从该数组创建对象,以 id 为键(key),数组项为值。

例如:

let users = [
  {id: 'john', name: "John Smith", age: 20},
  {id: 'ann', name: "Ann Smith", age: 24},
  {id: 'pete', name: "Pete Peterson", age: 31},
];

let usersById = groupById(users);

/*
// 调用函数后,我们应该得到:

usersById = {
  john: {id: 'john', name: "John Smith", age: 20},
  ann: {id: 'ann', name: "Ann Smith", age: 24},
  pete: {id: 'pete', name: "Pete Peterson", age: 31},
}
*/

处理服务端数据时,这个函数很有用。

在这个任务里我们假设 id 是唯一的。没有两个具有相同 id 的数组项。

请在解决方案中使用数组的 .reduce 方法。

打开带有测试的沙箱。

解决方案

function groupById(array) {
return array.reduce((obj, value) => {
 obj[value.id] = value;
 return obj;
}, {})
}

打开带有测试的沙箱。

Iterable object(可迭代对象)

可迭代(Iterable) 对象是数组的泛化。这个概念是说任何对象都可以被定制为可在 for..of 循环中使用的对象。

数组是可迭代的。但不仅仅是数组。很多其他内建对象也都是可迭代的。例如字符串也是可迭代的。

如果从技术上讲,对象不是数组,而是表示某物的集合(列表,集合),for..of 是一个能够遍历它的很好的语法,因此,让我们来看看如何使其发挥作用。

Symbol.iterator

通过自己创建一个对象,我们就可以轻松地掌握可迭代的概念。

例如,我们有一个对象,它并不是数组,但是看上去很适合使用 for..of 循环。

比如一个 range 对象,它代表了一个数字区间:

let range = {
  from: 1,
  to: 5
};

// 我们希望 for..of 这样运行:
// for(let num of range) ... num=1,2,3,4,5

为了让 range 对象可迭代(也就让 for..of 可以运行)我们需要为对象添加一个名为 Symbol.iterator 的方法(一个专门用于使对象可迭代的内建 symbol)。

  1. for..of 循环启动时,它会调用这个方法(如果没找到,就会报错)。这个方法必须返回一个 迭代器(iterator) —— 一个有 next 方法的对象。
  2. 从此开始,for..of 仅适用于这个被返回的对象
  3. for..of 循环希望取得下一个数值,它就调用这个对象的 next() 方法。
  4. next() 方法返回的结果的格式必须是 {done: Boolean, value: any},当 done=true 时,表示循环结束,否则 value 是下一个值。

这是带有注释的 range 的完整实现:

let range = {
  from: 1,
  to: 5
};

// 1. for..of 调用首先会调用这个:
range[Symbol.iterator] = function() {

  // ……它返回迭代器对象(iterator object):
  // 2. 接下来,for..of 仅与下面的迭代器对象一起工作,要求它提供下一个值
  return {
    current: this.from,
    last: this.to,

    // 3. next() 在 for..of 的每一轮循环迭代中被调用
    next() {
      // 4. 它将会返回 {done:.., value :...} 格式的对象
      if (this.current <= this.last) {
        return { done: false, value: this.current++ };
      } else {
        return { done: true };
      }
    }
  };
};

// 现在它可以运行了!
for (let num of range) {
  alert(num); // 1, 然后是 2, 3, 4, 5
}

请注意可迭代对象的核心功能:关注点分离。

  • range 自身没有 next() 方法。
  • 相反,是通过调用 range[Symbol.iterator]() 创建了另一个对象,即所谓的“迭代器”对象,并且它的 next 会为迭代生成值。

因此,迭代器对象和与其进行迭代的对象是分开的。

从技术上说,我们可以将它们合并,并使用 range 自身作为迭代器来简化代码。

就像这样:

let range = {
  from: 1,
  to: 5,

  [Symbol.iterator]() {
    this.current = this.from;
    return this;
  },

  next() {
    if (this.current <= this.to) {
      return { done: false, value: this.current++ };
    } else {
      return { done: true };
    }
  }
};

for (let num of range) {
  alert(num); // 1, 然后是 2, 3, 4, 5
}

现在 range[Symbol.iterator]() 返回的是 range 对象自身:它包括了必需的 next() 方法,并通过 this.current 记忆了当前的迭代进程。这样更短,对吗?是的。有时这样也可以。

但缺点是,现在不可能同时在对象上运行两个 for..of 循环了:它们将共享迭代状态,因为只有一个迭代器,即对象本身。但是两个并行的 for..of 是很罕见的,即使在异步情况下。

ℹ️无穷迭代器(iterator)

无穷迭代器也是可能的。例如,将 range 设置为 range.to = Infinity,这时 range 则成为了无穷迭代器。或者我们可以创建一个可迭代对象,它生成一个无穷伪随机数序列。也是可能的。

next 没有什么限制,它可以返回越来越多的值,这是正常的。

当然,迭代这种对象的 for..of 循环将不会停止。但是我们可以通过使用 break 来停止它。

字符串是可迭代的

数组和字符串是使用最广泛的内建可迭代对象。

对于一个字符串,for..of 遍历它的每个字符:

for (let char of "test") {
  // 触发 4 次,每个字符一次
  alert( char ); // t, then e, then s, then t
}

对于代理对(surrogate pairs),它也能正常工作!(译注:这里的代理对也就指的是 UTF-16 的扩展字符)

let str = '

标签:arr,迭代,编程语言,JavaScript,数据类型,alert,let,数组,name
From: https://blog.csdn.net/weixin_51568389/article/details/126448387

相关文章

  • 1、变量和简单数据类型
    1.1变量的命名和适用①必须是字母,数字,下划线。不能数字开头message="xxxx"1_message="xxxx"(不行)_message="xxx"0="xxx"(不行)②常变量名之间不能有空格greetingmessage="xxx"(不行)greeting_message="xxx"③不能用......
  • [JavaScript]“复杂”的 this
    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)https://www.cnblogs.com/cnb-yuchen/p/18277656出自【进步*于辰的博客】参考笔记二,P6.1;笔记三,P72、P73.1。先言我很早就知晓JS的这个知识点——this的重要性,并特意系统学习、理解并有所笔记,但限于平日用得少,对......
  • 第二章·数据类型与运算符
    第二章·数据类型与运算符文章目录第二章·数据类型与运算符数据类型分类基本数据类型整型(int)浮点型(float)复数(complex)属性与方法字符串(str)表示方式字符串运算符字符串的常见操作替换:replace()分割:split()去除两侧空格:strip()格式化输出索引和切片大小写转换查找......
  • [JS] 数据类型与特殊值的判断方法
    由于JS是弱类型语言,判断一个变量的数据类型是一个很常见的需求。下面介绍一些常用的判断方法:typeof操作符typeof可以用来判断除了``null的基本数据类型和function,其它引用数据类型都会返回object`。console.log(typeof"Hello");//"string"console.log(typeof42);//"num......
  • 【Redis二】Redis数据类型
    目录一.Redis数据类型分布二.字符串类型string 1.概述2.操作三.列表list1.概述2.操作四.哈希hash1.概述2.操作五.无序集合set1.概述2.应用范围3.操作六.有序集合zset1.概述2.应用范围3.操作七.通用命令一.Redis数据类型分布通常Redis的数据类型有五大......
  • “了解MySQL中的enum枚举数据类型“
    目录#开篇1.创建包含枚举类型的表2.插入枚举类型的数据3.查询包含枚举类型的表4.更新枚举类型的数据5.使用枚举类型的好处注意事项示例总结附加#开篇        在数据库中,枚举(ENUM)是一种数据类型,用于存储一组预定义的值。这在某些情况下非常有用,例如......
  • 【粉丝福利社】Hello Cangjie!华为仓颉编程语言震撼发布!(文末送书-进行中)
    ......
  • 哪种编程语言最省电?编程质量与耗电多少有关?
    能量使用数据是否能告诉我们编程语言的质量?图片去年,来自葡萄牙三所不同大学的六名研究人员决定调查这个问题,最终发布了一篇题为《编程语言的能效》的论文。他们在运行用27种不同语言编写的10个编程问题的解决方案时,监测了每种语言使用的电量、速度和内存使用情况。图......
  • 【JavaScript脚本宇宙】打造完美用户体验:必备JS图形库指南
    探索顶尖JavaScript图形库:从jsPlumb到mxGraph前言在现代的Web开发中,交互式图形和数据可视化库成为了不可或缺的工具。这些库不仅提供了丰富的功能,还大大简化了开发人员的工作流程。本文将介绍和比较六个流行的JavaScript图形和数据可视化库:jsPlumb、GoJS、draw2d、Cytosca......
  • 【JavaScript脚本宇宙】加速您的网站:图像优化工具和库的终极指南
    别让大图拖垮你的应用:如何正确优化图像前言在数字时代,图像是我们日常生活中不可或缺的一部分。然而,随着图像数量的增加和分辨率的提高,它们也占据了越来越多的存储空间和带宽。为了解决这个问题,开发人员可以使用各种图像优化工具和技术来减小图像文件的大小,同时保持其质量......