最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript - more efficient way to truncate an array - Stack Overflow

programmeradmin5浏览0评论

I have an int array sorted ascending and I would like to remove array items from the tail according to the specific boundary. What is a better way to truncate an array in my case? Consider next code snippets:

var a = [1, 2, 3, 4];
var length = a.length;
var boundary = 2;
var count = 0;
for (var i = length - 1; i >= 0; i--) {
    if (a[i] > boundary) {
        a[i] = null; // or delete a[i] ???
        count++;
    }
}
a.length -= count;

Or the same but using splice:

for (var i = length - 1; i >= 0; i--) {
    if (a[i] > boundary) {
        a.splice(i, 1);
    }
}

I have an int array sorted ascending and I would like to remove array items from the tail according to the specific boundary. What is a better way to truncate an array in my case? Consider next code snippets:

var a = [1, 2, 3, 4];
var length = a.length;
var boundary = 2;
var count = 0;
for (var i = length - 1; i >= 0; i--) {
    if (a[i] > boundary) {
        a[i] = null; // or delete a[i] ???
        count++;
    }
}
a.length -= count;

Or the same but using splice:

for (var i = length - 1; i >= 0; i--) {
    if (a[i] > boundary) {
        a.splice(i, 1);
    }
}
Share Improve this question asked Dec 22, 2017 at 22:14 AlexAlex 721 silver badge10 bronze badges 4
  • 1 Those two snippets of code do very different things, and neither of them remove elements that are only on the tail. To see what I mean, use [4, 3, 2, 1] as your array. – castletheperson Commented Dec 22, 2017 at 22:21
  • My array is always sorted ascending. – Alex Commented Dec 22, 2017 at 22:25
  • 1 Ah, I didn't notice that detail. You should be using a binary search then. – castletheperson Commented Dec 22, 2017 at 22:27
  • Good point! Didn't think about that but need to give it a try! – Alex Commented Dec 22, 2017 at 22:29
Add a ment  | 

3 Answers 3

Reset to default 8
 a.length -= count;

Thats sufficient ;) (as length is not a simple property, but rather a getter/setter which truncates/adds elements (ref))

Alternatively use splice:

 a.splice(-count, count);

In modern engines, or with a shim, you can use Array.prototype.findIndex:

var a = [1, 2, 3, 4];
var boundary = 2;
a.length = a.findIndex( x => x > boundary );
console.log( a );

Since you're array is sorted you can also just use Array.prototype.filter:

var a = [1, 2, 3, 4];
var boundary = 2;
a = a.filter( x => x <= boundary );
console.log( a );

which may be slightly (negligibly) slower if the array is huge, but has more support in older engines.

Don't delete array entries at the end of an array to truncate it. Deleting array entries removes them from the array by creating a sparse array: the length property of the array remains unchanged:

var a = [1,2,3,4];
console.log( "a.length %s", a.length);
delete a[3];
console.log( "a[3] after deletion: %s", a[3]);
console.log( "a.length after deletion %s", a.length);
console.log( "a[3] still exists: %s", a.hasOwnProperty("3"));

Similar considerations apply to setting array entries to null. They will no longer test as truthy in a conditional expression, but have not been removed. As before the length of the array will remain unchanged.

Setting the length of the an array to something shorter than its existing value will truncate it in place. There are many ways of finding the boundary position at which to truncate the array. I suggest choosing one that appears natural to you and works in target browsers. E.G. using forSome on a sorted array may not meet your requirements :)

var a = [1,2,3,4];
var boundary = 2;
a.some(
   (c,i) => {
      if( c > boundary)
      {  a.length = i;
         return true;
      }
   }
);

console.log( a)

If using splice, note that all entries from the boundary position to the end of array can be deleted in one call rather than deleting them one at a time:

var a = [1,2,3,4];
var boundary = 2;
for( var i = a.length-1; a[i]>boundary; --i) {} // linear search
a.splice(i+1);
console.log(a);

发布评论

评论列表(0)

  1. 暂无评论