移动数组中的指定字符

Move specified characters in an array

本文关键字:字符 数组 移动      更新时间:2023-09-26

我得到一个作为参数给出的元素列表,这是输入。

JSON.stringify(moveZeros([1,2,0,1,0,1,0,3,0,1]))

脚本应将零移动到末尾,而不更改其他元素的顺序。我的解决方案类似于以下代码:

var moveZeros = function (arr) {
  var args = Array.prototype.slice.call(arguments);
  for(var i=0; i<args.length; i++) {
        if (args[i] == 0)
           args.splice(i);
           args.push(0);
  }
  console.log(args);
  return args;
}

这应该将元素附加为零值,并将一个新的 0 值附加到数组的末尾。它只打印原始数组而不进行修改。

这是因为参数是传入的所有参数。您应该使用arr而不是参数。

var moveZeros = function (arr) {
  var args = arr;
  ...
}

您将面临的另一个问题是,当您从开始循环到结束并将元素移动到末尾时,您将跳过索引,因为内容向下滑动以填充刚刚创建的洞。如果您使用的是 for 循环,则应从末尾到开头使用 reduce() 或循环。

var moveZeros = function(arr) {
  var args = arr;
  for (var i = args.length - 1; i >= 0; i--) {
    if (args[i] === 0) {
      args.splice(i, 1);
      args.push(0);
    }
  }
  return args;
}
console.log(JSON.stringify(moveZeros([1, 2, 0, 1, 0, 1, 0, 3, 0, 1])));

您可以使用 arr 的副本并使用变量进行长度检查。如果找到零,则长度变量递减,并将零推到末尾。如果未找到,则索引递增。

var moveZeros = function (arr) {
    var args = arr.slice(),
        i = 0,
        l = args.length;
    while (i < l) {
        if (args[i] === 0) {
            args.push(args.splice(i, 1)[0]);
            l--;
        } else {
            i++;
        }
    }
    return args;
}
console.log(moveZeros([1, 2, 0, 1, 0, 1, 0, 3, 0, 1]));

或者从最后使用循环。

var moveZeros = function (arr) {
    var args = arr.slice(),
        i = args.length;
    while (i--) {
        if (args[i] === 0) {
            args.push(args.splice(i, 1)[0]);
        }
    }
    return args;
}
console.log(moveZeros([1, 2, 0, 1, 0, 1, 0, 3, 0, 1]));

你有一些括号错误,错过了一些论点。此外,您使用数组作为参数,无需对参数进行切片。您还错过了splice的元素数量

这不适用于类似[9, 0, 9, 1, 2, 1, 1, 3, 1, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0]的东西(请参阅下面的进一步更新)

// DOES NOT WORK
var moveZeros = function (arr) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] == 0) {
            arr.splice(i, 1);
            arr.push(0);
        }
    }
    console.log(arr);
    return arr;
}

工作解决方案

    var moveZeros = function(args) {
        var r = [];
        var zeros = 0;
        for (var i = 0; i < args.length; i++) {
            if (args[i] !== 0) {
                r.push(args[i]);
            } else zeros++
        }
        r = r.concat(Array(zeros).fill(0))
        console.log(r);
        return args;
    }
    JSON.stringify(moveZeros([9, 0, 9, 1, 2, 1, 1, 3, 1, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0]));

您必须提供要在 splice() 方法中删除的值count

仅当值0时,才推送0。你每次都在推动它。(提示:因为推送语句不在if中)。

使用数组的副本:

您可以维护一个新数组并仅将非 zzero 值推送到该数组上,然后推送所有零。简单易懂。

var moveZeros = function(args) {
  var arr = [], zCount = 0;
  for (var i = 0; i < args.length; i++) {
    args[i] == 0 ? zCount++ : arr.push(args[i]);
  }
  while (zCount-- > 0) arr.push(0);
  console.log(arr);
  return arr;
}
JSON.stringify(moveZeros([9, 0, 0, 0, 9, 1, 2, 1, 1, 3, 1, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0]));

带反向循环:你需要一个反向循环,因为每次拼接时都会跳过一个索引,这样重复的 0 就不会被删除。

var moveZeros = function(args) {
  for (var i = args.length; i > 0; i--) {
    if (args[i] == 0) {
      args.splice(i, 1);
      args.push(0);
    }
  }
  console.log(args);
  return args;
}
JSON.stringify(moveZeros([9, 0, 0, 0, 9, 1, 2, 1, 1, 3, 1, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0]));

我认为这将是

最有趣的方式,也是最好的代码行,并且由于它使用内置函数(排序),因此它面临的性能问题较少。

var array = [1, 2, 0, -1, 0, 1, 0, 3, 0, 1]
array.sort(a => a === 0);
console.log(array);

首先,在迭代数组时修改数组是不好的。 这可能会导致一些奇怪的跳跃,令人困惑。假设你有 1,0,0,1在你的循环中,当你到达索引一个时,它会拼接并将零附加到数组的末尾1,0,1,0但是计数器随后将增加到 2,并且它将错过现在位于位置 1 的 0。

看起来您正在尝试创建一个浅拷贝

var args = Array.prototype.slice.call(arguments);

但我不太确定。我不会修改您要返回的数组,而是创建一些临时数组并循环输入,如果它 0 上升某个计数器,如果它不是 0 将其推送到保持数组,然后推送计数器告诉您的尽可能多的 0 并返回临时数组