我正在寻找一个JavaScript数组插入方法,样式如下:
arr.insert(index, item)
最好是在jQuery中,但此时任何JavaScript实现都可以。
我正在寻找一个JavaScript数组插入方法,样式如下:
arr.insert(index, item)
最好是在jQuery中,但此时任何JavaScript实现都可以。
当前回答
解决方案和性能
今天(2020.04.24),我为大型和小型阵列选择的解决方案进行测试。我在Chrome 81.0、Safari 13.1和Firefox 75.0上的macOS v10.13.6(High Sierra)上测试了它们。
结论
适用于所有浏览器
令人惊讶的是,对于小型阵列,基于切片和归约(D,E,F)的非就地解决方案通常比就地解决方案快10x-100倍对于大型阵列,基于拼接(AI、BI和CI)的就地解决方案是最快的(有时约为100倍,但取决于阵列大小)对于小型阵列,BI解决方案是最慢的对于大型阵列,E解决方案是最慢的
细节
测试分为两组:就地解决方案(AI、BI和CI)和非就地解决方案,分别针对两种情况进行:
测试包含10个元素的数组-可以在此处运行测试具有1000000个元素的数组-可以在此处运行
测试代码显示在以下代码段中:
小提琴演奏家
函数AI(arr,i,el){arr.splice(i,0,el);返回arr;}功能BI(arr,i,el){阵列.原型.拼接.应用(arr,[i,0,el]);返回arr;}函数CI(arr,i,el){数组.原型.拼接.调用(arr,i,0,el);返回arr;}函数D(arr,i,el){返回arr.slice(0,i).contat(el,arr.slices(i));}函数E(arr,i,el){return[…arr.slice(0,i),el,…arr.slime(i)]}函数F(arr,i,el){返回arr.reduce((s,a,j)=>(j-i?s.push(a):s.push(el,a),s),[]);}// -------------//测试// -------------设arr=[“a”、“b”、“c”、“d”、“e”、“f”];设log=(n,f)=>{设a=f([…arr],3,“新”);console.log(`${n}:[${a}]`);};日志('AI',AI);日志('BI',BI);日志('CI',CI);日志('D',D);对数('E',E);日志('F',F);此代码段仅显示测试代码(不执行测试)
Google Chrome上一个小数组的示例结果如下:
其他回答
尽管这个问题已经得到了回答,但我还是添加了这个注释作为替代方法。
我想将已知数量的项目放入一个数组中,放入特定位置,因为它们来自一个“关联数组”(即一个对象),根据定义,该数组不能保证按排序顺序排列。我希望得到的数组是一个对象数组,但是对象在数组中的顺序是特定的,因为数组保证了它们的顺序。所以我这样做了。
首先是源对象,一个从PostgreSQL检索的JSONB字符串。我想让它按每个子对象中的“order”属性排序。
var jsonb_str = '{"one": {"abbr": "", "order": 3}, "two": {"abbr": "", "order": 4}, "three": {"abbr": "", "order": 5}, "initialize": {"abbr": "init", "order": 1}, "start": {"abbr": "", "order": 2}}';
var jsonb_obj = JSON.parse(jsonb_str);
由于对象中的节点数是已知的,因此我首先创建一个具有指定长度的数组:
var obj_length = Object.keys(jsonb_obj).length;
var sorted_array = new Array(obj_length);
然后迭代对象,将新创建的临时对象放置到数组中所需的位置,而不进行任何“排序”。
for (var key of Object.keys(jsonb_obj)) {
var tobj = {};
tobj[key] = jsonb_obj[key].abbr;
var position = jsonb_obj[key].order - 1;
sorted_array[position] = tobj;
}
console.dir(sorted_array);
Array#splice()是最好的方法,除非你真的想避免改变数组。给定2个数组arr1和arr2,下面是如何将arr2的内容插入到arr1的第一个元素之后:
常量arr1=[‘a’,‘d’,‘e’];常量arr2=['b','c'];arr1.拼接(1,0,…arr2);//arr1现在包含[a','b','c','d','e']控制台日志(arr1)
如果您担心数组的变异(例如,如果使用Immutable.js),可以改用slice(),不要与带有“p”的splice()混淆。
const arr3 = [...arr1.slice(0, 1), ...arr2, ...arr1.slice(1)];
您可以使用array.spling执行此操作:
/**
* @param arr: Array
* @param item: item to insert
* @param index: index at which to insert
* @returns array with the inserted element
*/
export function _arrayInsertAt<T>(arr: T[], item: T, index: number) {
return arr.splice(index, 0, item);;
}
阵列切片的文档
自定义数组插入方法
1.具有多个参数和链接支持
/* Syntax:
array.insert(index, value1, value2, ..., valueN) */
Array.prototype.insert = function(index) {
this.splice.apply(this, [index, 0].concat(
Array.prototype.slice.call(arguments, 1)));
return this;
};
它可以插入多个元素(与原生拼接一样)并支持链接:
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6);
// ["b", "X", "Y", "Z", "c"]
2.支持数组类型参数合并和链接
/* Syntax:
array.insert(index, value1, value2, ..., valueN) */
Array.prototype.insert = function(index) {
index = Math.min(index, this.length);
arguments.length > 1
&& this.splice.apply(this, [index, 0].concat([].pop.call(arguments)))
&& this.insert.apply(this, arguments);
return this;
};
它可以将参数中的数组与给定数组合并,还支持链接:
["a", "b", "c", "d"].insert(2, "V", ["W", "X", "Y"], "Z").join("-");
// "a-b-V-W-X-Y-Z-c-d"
演示:http://jsfiddle.net/UPphH/
任何对这个问题仍有疑问的人,都尝试过前面答案中的所有选项,但都没有得到。我分享我的解决方案,这是为了考虑到您不想显式地声明对象与数组的财产。
function isIdentical(left, right){
return JSON.stringify(left) === JSON.stringify(right);
}
function contains(array, obj){
let count = 0;
array.map((cur) => {
if(this.isIdentical(cur, obj))
count++;
});
return count > 0;
}
这是对引用数组进行迭代并将其与要检查的对象进行比较的组合,将两者转换为字符串,然后在匹配时进行迭代。然后你就可以数了。这是可以改进的,但这是我解决的问题。