You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript数组中保留锁定元素位置,仅打乱未锁定元素?

实现仅打乱未锁定元素的解决方案

原代码存在的问题

  1. 语法错误:原始data数组中的对象属性未加逗号,会导致JS解析失败;重复声明data变量(const data = shuffle(locked);)违反const变量规则。
  2. 逻辑缺陷:仅筛选并打乱未锁定元素,丢失了原数组中的锁定元素,没有实现“保留锁定元素位置、仅打乱未锁定元素”的核心需求。
  3. API误用:使用filter的方式不符合其设计意图,filter应返回布尔值用于筛选元素,而非用来遍历执行push操作。

修正后的实现代码

// 已锁定元素的ID集合
const lockedIds = ["b79bc2a0-da09-4620-9b3d-1ed32d697f0a", "a60d0c77-439d-4764-b115-f4c24f857cd1"];

// 原始数据(修正语法错误,对象属性间添加逗号)
const originalData = [
  {
      id: "b79bc2a0-da09-4620-9b3d-1ed32d697f0a",
      name: "three",
      email: "three@gmail.com"
  },
  {
      id: "c8648167-3103-44f9-b03c-3bd951fb339c",
      name: "two",
      email: "two@gmail.com"
  },
  {
      id: "a60d0c77-439d-4764-b115-f4c24f857cd1",
      name: "one",
      email: "one@gmail.com"
  }
];

// Fisher-Yates洗牌算法(你的实现是正确的,这里添加了数组副本返回避免修改原数组)
function shuffle(array) {
  const shuffled = [...array];
  let currentIndex = shuffled.length, randomIndex;
  
  while (currentIndex !== 0) {
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex--;
    [shuffled[currentIndex], shuffled[randomIndex]] = [shuffled[randomIndex], shuffled[currentIndex]];
  }
  
  return shuffled;
}

// 核心逻辑:保留锁定元素位置,仅打乱未锁定元素
function shuffleUnlockedItems(data, lockedIds) {
  // 1. 筛选出未锁定元素并打乱
  const unlockedShuffled = shuffle(data.filter(item => !lockedIds.includes(item.id)));
  
  // 2. 遍历原数组,构建新结果:锁定元素直接保留,未锁定元素用打乱后的填充
  let unlockedPointer = 0;
  return data.map(item => {
    return lockedIds.includes(item.id) ? item : unlockedShuffled[unlockedPointer++];
  });
}

// 使用示例
const result = shuffleUnlockedItems(originalData, lockedIds);
console.log(result);

逻辑说明

  1. 分离与打乱:先通过filter筛选出所有未锁定元素,用洗牌算法打乱它们的顺序。
  2. 重构数组:遍历原始数组,遇到锁定元素直接保留其位置和内容;遇到未锁定元素时,从打乱后的未锁定数组中依次取元素填充,确保锁定元素的位置完全不变,仅未锁定元素被随机排序。

这个方案完全满足你“点击锁定按钮后仅对未被锁定的元素进行随机打乱”的需求。

内容的提问来源于stack exchange,提问作者Jackson Quintero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:25:15