如何调整数组大小

时间:2015-08-17 15:27:51

标签: javascript arrays

是否有一个可以替换以下函数的Array方法(类似于a.splice(some, tricky, arguments))?

function resize(arr, newSize, defaultValue) {
  if (newSize > arr.length)
    while(newSize > arr.length)
      arr.push(defaultValue);
  else
    arr.length = newSize;
}

如果没有,是否有更好/更好/更短/实施?如果数组应该增长并且在shrink上删除值,该函数应该附加一个默认值。

6 个答案:

答案 0 :(得分:6)

在优雅方面,我会说你可以减少原来的解决方案:

function resize(arr, newSize, defaultValue) {
    while(newSize > arr.length)
        arr.push(defaultValue);
    arr.length = newSize;
}

或使用原型:

Array.prototype.resize = function(newSize, defaultValue) {
    while(newSize > this.length)
        this.push(defaultValue);
    this.length = newSize;
}

答案 1 :(得分:4)

function resize(arr, size, defval) {
    while (arr.length > size) { arr.pop(); }
    while (arr.length < size) { arr.push(defval); }
}

我认为这会更有效率:

function resize(arr, size, defval) {
    var delta = arr.length - size;

    while (delta-- > 0) { arr.pop(); }
    while (delta++ < 0) { arr.push(defval); }
}

虽然不那么优雅,但这可能是我最有效率的:

function resize(arr, size, defval) {
    var delta = arr.length - size;

    if (delta > 0) {
        arr.length = size;
    }
    else {
        while (delta++ < 0) { arr.push(defval); }
    }
}

答案 2 :(得分:1)

This solution will only work for new browsers (accept IE) due to Array.prototype.fill(请参阅链接页面底部的浏览器兼容性)或使用填充。

function resize(arr, newSize, defaultValue) {
    var originLength = arr.length; // cache original length

    arr.length = newSize; // resize array to newSize

    (newSize > originLength) && arr.fill(defaultValue, originLength); // Use Array.prototype.fill to insert defaultValue from originLength to the new length
}

答案 3 :(得分:1)

扩展詹姆斯解决方案:

Array.prototype.resize = function(newSize, defaultValue) {
    while(newSize > this.length)
        this.push(defaultValue);
    this.length = newSize;
}

如果您想提高效率,可以对Array.prototype.fill进行浏览器检测并使用它而不是while循环。

if (Array.prototype.fill) {
    Array.prototype.resize = function (size, defaultValue) {
        var len = this.length;

        this.length = size;

        if (this.length - len > 0)
            this.fill(defaultValue, len);
    };
} else {
    Array.prototype.resize = function (size, defaultValue) {
        while (size > this.length)
            this.push(defaultValue);

        this.length = size;
    };
}

如果有人为Array.prototype.fill添加了填充,那么您希望他们使用您的非填充版本。 polyfill会导致fill方法比非填充版本慢。

这个StackOverflow Q&A讨论如何检测函数是否是本机实现的。您可以将其用于初始条件,但这只是额外的速度损失。

如果可以确保不存在Array.prototype.fill,我可能只会使用此解决方案。

答案 4 :(得分:0)

one-liner-lovers

如果你像我一样 one-liner-lover , 你要问的是我的resize_array_right会做什么。

const resize_array_left = (array, length, fill_with) => (new Array(length)).fill(fill_with).concat(array).slice(-length);
// Pads left when expanding an array.
// Put left elements first to be removed when shrinking an array.

const resize_array_right = (array, length, fill_with) => array.concat((new Array(length)).fill(fill_with)).slice(0, length);
// Pads right when expanding an array.
// Put right elements first to be removed when shrinking an array.

您可以在 NPM 中找到它,resize-array

浏览器兼容性

  • Chrome:45及以上。
  • Firefox:31岁及以上。
  • Internet Explorer:✘。
  • 边缘:✔。

答案 5 :(得分:0)

您可以使用以下代码来调整数组的大小:

// resizing function for arrays
Array.prototype.resize = function( newSize, defaultValue )
{
  while( newSize > this.length )
  {
    typeof( defaultValue ) === "object" ? this.push( Object.create( defaultValue ) ) : this.push( defaultValue );
  }
  this.length = newSize;
}

我检查了defaultValue的类型,因为如果它是一个对象,而只是将其推入新元素,则将得到一个数组,其中新元素指向同一对象。这意味着,如果您在数组元素之一中更改该对象的属性,则所有其他元素也会更改。但是,如果您的defaultValue是原始元素,则可以安全地将其推送到新元素。