gpt4 book ai didi

JavaScript:有没有更好的方法来保留数组但有效地连接或替换项目?

转载 作者:行者123 更新时间:2023-11-30 05:43:03 26 4
gpt4 key购买 nike

我正在寻找在不删除原始引用的情况下替换或添加数组元素的最佳方法。这是设置:

var a = [], b = [], c, i, obj;
for ( i = 0; i < 100000; i++ ) { a[ i ] = i; b[ i ] = 10000 - i; }
obj.data_list = a;

现在我们想在不更改对 a 的引用的情况下将 b 连接到 a,因为它在 obj.data_list 中使用。这是一种方法:

for ( i = 0; i < b.length; i++ ) { a.push( b[ i ] ); }

这似乎是一种更简洁且(在 V8 上)快 8 倍的方法:

a.splice.apply( a, [ a.length, 0 ].concat( b ) );

我发现这在遍历“就地”数组时很有用,并且不想在我进行时触摸元素(一个好习惯)。我用初始参数启动一个新数组(我们称之为 keep_list),然后添加我希望保留的元素。最后我使用这个 apply 方法来快速替换被 chop 的数组:

var keep_list = [ 0, 0 ];
for ( i = 0; i < a.length; i++ ){
if ( some_condition ){ keep_list.push( a[ i ] );
}

// truncate array
a.length = 0;

// And replace contents
a.splice.apply( a, keep_list );

此解决方案存在一些问题:

  • V8 上的最大调用堆栈大小限制约为 50k
  • 我还没有在其他 JS 引擎上测试过。
  • 这个解决方案有点神秘

有没有人找到更好的方法?

最佳答案

可能最全面但仍然有效的方法是使用 push

var source = [],
newItems = [1, 2, 3];

source.push.apply(source, newItems);

如果达到最大调用堆栈,您可以将操作分成多个批处理。

var source = [],
newItems = new Array(500000),
i = 0,
len = newItems.length,
batch;

for (; i < len; i++) newItems[i] = i;

//You need to find a real cross-browser stack size, here I just used 50k
while((batch = newItems.splice(0, 50000)).length) {
source.push.apply(source, batch);
}

console.log(source[499999]);

另外请记住,昂贵的操作可能会挂起浏览器,尤其是在 JS 引擎速度较慢的旧浏览器中。为避免此问题,您可以进一步将进程拆分为更小的批处理,并使用 setTimeout 让浏览器喘口气。

最后,我想到的另一种方法是在您的数组周围使用一个包装器对象,这样您就可以直接替换数组,因为您的引用将通过该对象保留。

var arrWrapper = { list: [] },
obj1 = { items: arrWrapper },
obj2 = { items: arrWrapper };

//update the array
obj2.items.list = [1, 2, 3, 4];

//access the array
obj1.items.list;

唯一的限制是避免直接引用 arrWrapper.list

注意:如果您只针对现代浏览器,您可以使用 WebWorkers .但是据我所知,您只能传递序列化数据,这意味着工作人员无法直接修改源数组。

关于JavaScript:有没有更好的方法来保留数组但有效地连接或替换项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19672848/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com