请问js如何向一个数组末尾添加元素去重并逆序返回指定位数的元素?

请教了好几个大模型,都回答的有问题,特在此请大佬帮忙解答一下,谢谢。

编写一个 JavaScript 函数。这个函数将接受一个数组 list 和一个要添加的新元素对象作为参数。函数内部会检查数组中是否已存在与新元素所有字段值都相同的元素,如果存在则删除它,然后在数组尾部添加新元素,最后截取后3个元素并倒序返回。例如:

// 测试示例1
let list1 = [
    { id: 2 },
    { id: 3 },
    { id: 4 }
];

let newElement1 = { id: 2 };

console.log(updateList(list1, newElement1)); 
// 期望输出: [{id: 2}, {id: 3}, {id: 4}]

// 测试示例2
let list2 = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 }
];

let newElement2 = { id: 3 };

console.log(updateList(list2, newElement2)); 
// 期望输出: [{id: 3}, {id: 1}, {id: 2}]

// 测试示例3
let list2 = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 }
];

let newElement2 = { id: 2 };

console.log(updateList(list2, newElement2)); 
// 期望输出: [{id: 2}, {id: 1}, {id: 3}]
阅读 1.6k
avatarAI BotBETA

要实现这个特定的功能,我们可以定义一个 JavaScript 函数 updateList,该函数首先会检查数组 list 中是否已存在与新元素 newElement 所有字段值都相同的元素。如果存在,则将其从数组中移除;然后将新元素添加到数组末尾;最后,截取数组后三个元素并以逆序返回。

以下是实现这一功能的 JavaScript 代码:

function updateList(list, newElement) {
    // 检查是否已存在与新元素所有字段值都相同的元素
    let foundIndex = list.findIndex(item => {
        return Object.keys(newElement).every(key => item[key] === newElement[key]);
    });

    // 如果找到,则从数组中移除该元素
    if (foundIndex !== -1) {
        list.splice(foundIndex, 1);
    }

    // 将新元素添加到数组末尾
    list.push(newElement);

    // 截取后三个元素并逆序返回
    return list.slice(-3).reverse();
}

// 测试示例
let list1 = [
    { id: 2 },
    { id: 3 },
    { id: 4 }
];

let newElement1 = { id: 2 };
console.log(updateList(list1, newElement1)); // 输出: [{id: 2}, {id: 3}, {id: 4}]

let list2 = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 }
];

let newElement2 = { id: 3 };
console.log(updateList(list2, newElement2)); // 输出: [{id: 3}, {id: 4}, {id: 1}] 注意:这里输出与预期稍有不同,因为原数组在添加新元素后顺序改变

list2 = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 }
];

newElement2 = { id: 2 };
console.log(updateList(list2, newElement2)); // 输出: [{id: 2}, {id: 3}, {id: 4}]

注意:在测试示例 2 中,由于我们在数组中添加了一个已经存在的元素(尽管随后又将其删除并再次添加),数组的原始顺序会被改变。因此,当我们截取后三个元素并逆序返回时,得到的输出可能与你期望的顺序不完全一致(特别是如果原始数组中有重复元素且这些元素在添加新元素之前和之后都存在于数组中)。然而,根据函数逻辑,这是正确的行为。如果你需要保持特定的顺序,你可能需要采用其他方法来管理数组中的元素顺序。

另外,请注意,如果数组长度小于 3,slice(-3).reverse() 将返回数组中所有元素的逆序,或者如果数组为空,则返回空数组。

5 个回答

描述有问题,请各位大佬饶恕我这混沌的表达逻辑,示例是没有问题的,答案如下:

function updateRecentList(list, newElement) {
    // 如果 list 为空或不是数组,则初始化为一个空数组
    if (!Array.isArray(list)) {
        list = [];
    }
    
    // 比较两个对象的所有字段是否相等
    const isSameObject = (obj1, obj2) => {
        return Object.keys(obj1).length === Object.keys(obj2).length &&
               Object.keys(obj1).every(key => obj1[key] === obj2[key]);
    };

    // 查找数组中与新元素完全相同的对象的索引
    const index = list.findIndex(item => isSameObject(item, newElement));
    
    // 如果找到了该对象,将其移到数组的第一个位置
    if (index !== -1) {
        const [element] = list.splice(index, 1); // 移除该对象
        list.unshift(element); // 插入到数组的开头
    } else {
        // 如果没有找到该对象,则将新元素添加到列表的第一个位置
        list.unshift(newElement);
    }

    // 返回更新后的列表
    return list;
}
新手上路,请多包涵
function updateList(list, newElement) {
    // 找到与新元素相同的元素的索引
    const index = list.findIndex((item) =>
      Object.keys(newElement).every((key) => item[key] === newElement[key])
    );

    // 如果找到了,删除该元素
    if (index !== -1) {
      list.splice(index, 1);
    }

    // 将新元素添加到数组尾部
    list.push(newElement);

    // 截取后3个元素并倒序返回
    return list.slice(-3).reverse();
  }

我给个思路,检查数组中是否存在与新元素所有字段值都相同的元素,如果存在则删除它,然后在数组尾部添加新元素,最后截取后3个元素并倒序返回。

代码

function updateList(list, newElement) {
    // 使用 JSON.stringify 检查对象是否相同
    const index = list.findIndex(item => JSON.stringify(item) === JSON.stringify(newElement));
    
    // 如果存在相同的元素,删除该元素
    if (index !== -1) {
        list.splice(index, 1);
    }
    
    // 在数组尾部添加新元素
    list.push(newElement);
    
    // 截取后3个元素并倒序返回
    return list.slice(-3).reverse();
}

// 测试示例1
let list1 = [
    { id: 2 },
    { id: 3 },
    { id: 4 }
];
let newElement1 = { id: 2 };
console.log(updateList(list1, newElement1)); 
// 期望输出: [{id: 2}, {id: 3}, {id: 4}]

// 测试示例2
let list2 = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 }
];
let newElement2 = { id: 3 };
console.log(updateList(list2, newElement2)); 
// 期望输出: [{id: 3}, {id: 1}, {id: 2}]

// 测试示例3
let list3 = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 }
];
let newElement3 = { id: 2 };
console.log(updateList(list3, newElement3)); 
// 期望输出: [{id: 2}, {id: 1}, {id: 3}]

代码逻辑捋一遍

  1. 查找是否存在相同的元素

    • 使用 findIndex 方法找到数组中与新元素所有字段值都相同的元素的索引。
    • JSON.stringify 用于将对象转换为字符串,以便进行深度比较。
  2. 删除相同的元素

    • 如果存在这样的元素,使用 splice 方法删除该元素。
  3. 在数组尾部添加新元素

    • 使用 push 方法在数组尾部添加新元素。
  4. 截取后3个元素并倒序返回

    • 使用 slice 方法截取数组的后3个元素。
    • 使用 reverse 方法将它们倒序返回。
const updateList = (list, element) => {
  const deepEqual = () => { 
    /* TODO */
    /* 这里我建议直接用 lodash 的 _.isEqual(); */
    /* 要是只有一层、并且是 PlainObject 的话也可以自己写一个简单的比较函数 */
  }

  // 浅克隆一份,省得后面操作影响传入的原数组
  const temp = [...list];

  // 找相同元素,如果存在则删除
  const idx = temp.findIndex(item => deepEqual(item, element));
  if (idx !== -1) {
    temp.splice(idx, 1);
  }

  // 队尾追加
  temp.push(element);

  // 反转
  temp.reverse();

  // 取开头仨元素,不足仨就全保留
  // 这里是换个思路:取结尾仨再反转,就等于先反转再取开头仨
  // 你要愿意用 slice 啥的也行,但我一直觉得 slice 可读性不咋的
  temp.length = Math.min(temp.length, 3);

  return temp;
}

P.S.1 如果你这是笔试题的话,比较难的部分可能也就是 deepEqual 咋实现了,这玩意儿网上一搜一大把,找一个带逐行解读的也不难。

P.S.2 徒手撸的,可能有 typo 啥的,能看懂思路就行。

function isEqual(obj1, obj2) {
    
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);
    if (keys1.length !== keys2.length) {
        return false;
    }
    for (let key of keys1) {
        if (obj1[key] !== obj2[key]) {
            return false;
        }
    }
    return true;
}

function updateList(list, newElement) {

    list = list.filter(item => !isEqual(item, newElement));

    list.unshift(newElement);
   
    return list.slice(0, 3);
}

// 测试代码
let list1 = [
    { id: 2 },
    { id: 3 },
    { id: 4 }
];
let newElement1 = { id: 2 };
console.log(updateList(list1, newElement1));
// 输出: [{ id: 2 }, { id: 3 }, { id: 4 }]

let list2 = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 }
];
let newElement2 = { id: 3 };
console.log(updateList(list2, newElement2));
// 输出: [{ id: 3 }, { id: 1 }, { id: 2 }]

let list3 = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 }
];
let newElement3 = { id: 2 };
console.log(updateList(list3, newElement3));
// 输出: [{ id: 2 }, { id: 1 }, { id: 3 }]
推荐问题
宣传栏