我正在寻找一个JavaScript数组插入方法,样式如下:
arr.insert(index, item)
最好是在jQuery中,但此时任何JavaScript实现都可以。
我正在寻找一个JavaScript数组插入方法,样式如下:
arr.insert(index, item)
最好是在jQuery中,但此时任何JavaScript实现都可以。
您需要在本机阵列对象上使用拼接函数。
arr.splice(索引,0,项);将在指定的索引处向arr中插入项目(首先删除0个项目,也就是说,这只是一个插入)。
在本例中,我们将创建一个数组,并将一个元素添加到索引2中:
var arr=[];arr[0]=“Jani”;arr[1]=“Hege”;arr[2]=“过时”;arr[3]=“Kai Jim”;arr[4]=“博格”;console.log(arr.jjoin());//Jani、Hege、Stale、Kai Jim、Borgearr.splice(2,0,“Lene”);console.log(arr.jjoin());//Jani、Hege、Lene、Stale、Kai Jim、Borge
如果您想一次将多个元素插入到数组中,请查看以下堆栈溢出答案:用javascript将数组拼接到数组中的更好方法
下面还有一些函数来说明这两个示例:
function insertAt(array, index) {
var arrayToInsert = Array.prototype.splice.apply(arguments, [2]);
return insertArrayAt(array, index, arrayToInsert);
}
function insertArrayAt(array, index, arrayToInsert) {
Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert));
return array;
}
最后,这里有一个jsFiddle,您可以自己看到它:http://jsfiddle.net/luisperezphd/Wc8aS/
这是如何使用这些函数的:
// if you want to insert specific values whether constants or variables:
insertAt(arr, 1, "x", "y", "z");
// OR if you have an array:
var arrToInsert = ["x", "y", "z"];
insertArrayAt(arr, 1, arrToInsert);
通过执行以下操作,可以实现Array.insert方法:
Array.prototype.insert = function ( index, ...items ) {
this.splice( index, 0, ...items );
};
然后你可以像这样使用它:
var arr = [ 'A', 'B', 'E' ];
arr.insert(2, 'C', 'D');
// => arr == [ 'A', 'B', 'C', 'D', 'E' ]
自定义数组插入方法
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/
尽管这个问题已经得到了回答,但我还是添加了这个注释作为替代方法。
我想将已知数量的项目放入一个数组中,放入特定位置,因为它们来自一个“关联数组”(即一个对象),根据定义,该数组不能保证按排序顺序排列。我希望得到的数组是一个对象数组,但是对象在数组中的顺序是特定的,因为数组保证了它们的顺序。所以我这样做了。
首先是源对象,一个从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.protocol.insert()的发明是必不可少的。实际上,如果拼接返回的是变异数组,而不是一个完全没有意义的空数组,那么它可能是完美的。因此,这就是:
Array.prototype.insert=函数(i,…rest){此.拼接(i,0,…其余)返回这个}变量a=[3,4,8,9];document.write(“<pre>”+JSON.stringify(a.insert(2,5,6,7))+“</pre>”);
好吧,好吧,上面的Array.prototype.splice()一个变异了原始数组,有些人可能会抱怨“你不应该修改不属于你的东西”,这可能也是正确的。因此,为了公益,我想提供另一个Array.prototype.insert(),它不会对原始数组进行变异。就这样;
Array.prototype.insert=函数(i,…rest){返回this.slice(0,i).contat(rest,this.slict(i));}变量a=[3,4,8,9],b=插入件(2,5,6,7);console.log(JSON.stringify(a));console.log(JSON.stringify(b));
除了拼接,您可以使用这种方法,它不会改变原始数组,但会使用添加的项创建一个新数组。当你需要避免突变时,它是有用的。我在这里使用ES6排列运算符。
常量项=[1,2,3,4,5]常量插入=(arr,索引,newItem)=>[//数组的指定索引之前的部分…arr.slice(0,索引),//插入的项目新项目,//指定索引之后的数组的一部分…arr.slice(索引)]常量结果=插入(项,1,10)console.log(结果)// [1, 10, 2, 3, 4, 5]
这可以用于添加多个项目,方法是稍微调整函数,为新项目使用rest运算符,并在返回的结果中传播:
常量项=[1,2,3,4,5]常量插入=(arr,索引,…newItems)=>[//数组的指定索引之前的部分…arr.slice(0,索引),//插入的项目…新项目,//指定索引之后的数组的一部分…arr.slice(索引)]常量结果=插入(项,1,10,20)console.log(结果)// [1, 10, 20, 2, 3, 4, 5]
我试过了,效果很好!
var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);
索引是要插入或删除元素的位置。
0,即第二个参数,定义要从索引中删除的元素的数量。项包含要在数组中创建的新条目。它可以是一个或多个。
initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
另一种可能的解决方案,使用Array.reduce。
const arr=[“苹果”、“橙色”、“覆盆子”];常量arr2=[1,2,4];常量插入=(arr,项,索引)=>arr.reduce(函数,a,i){i==索引?s.push(项目,a):s.push(a);返回s;}, []);console.log(插入(arr,“香蕉”,1));控制台日志(插入(arr2,3,2))
在这种情况下,我建议使用纯JavaScript。JavaScript中也没有任何insert方法,但我们有一个内置Array方法,它为您完成任务。这叫做拼接。。。
让我们看看什么是拼接()。。。
splice()方法通过删除现有元素和/或添加新元素。
好的,假设我们有下面这个数组:
const arr = [1, 2, 3, 4, 5];
我们可以这样删除3个:
arr.splice(arr.indexOf(3), 1);
它将返回3,但如果我们现在检查arr,我们有:
[1, 2, 4, 5]
到目前为止,还不错,但我们如何使用拼接将新元素添加到数组中?
让我们把三个放回。。。
arr.splice(2, 0, 3);
让我们看看我们做了什么。。。
我们再次使用拼接,但这次对于第二个参数,我们传递了0,这意味着我们不想删除任何项,但同时,我们添加了第三个参数,即将在第二个索引中添加的3。。。
您应该知道,我们可以同时删除和添加。例如,现在我们可以做到:
arr.splice(2, 2, 3);
这将删除索引2中的两个项目。然后在索引2处添加3,结果将是:
[1, 2, 3, 5];
这显示了拼接中的每个项目是如何工作的:
array.拼接(开始,删除计数,项目1,项目2,项目3…)
在特定索引处附加单个元素
// Append at a specific position (here at index 1)
arrName.splice(1, 0,'newName1');
// 1: index number, 0: number of element to remove, newName1: new element
// Append at a specific position (here at index 3)
arrName[3] = 'newName1';
在特定索引处附加多个元素
// Append from index number 1
arrName.splice(1, 0, 'newElemenet1', 'newElemenet2', 'newElemenet3');
// 1: index number from where append start,
// 0: number of element to remove,
//newElemenet1,2,3: new elements
任何对这个问题仍有疑问的人,都尝试过前面答案中的所有选项,但都没有得到。我分享我的解决方案,这是为了考虑到您不想显式地声明对象与数组的财产。
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;
}
这是对引用数组进行迭代并将其与要检查的对象进行比较的组合,将两者转换为字符串,然后在匹配时进行迭代。然后你就可以数了。这是可以改进的,但这是我解决的问题。
按以下方式计算减少方法的利润:
function insert(arr, val, index) {
return index >= arr.length
? arr.concat(val)
: arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
}
因此,通过这种方式,我们可以返回一个新数组(这将是一种很酷的函数方式,比使用push或splice要好得多),其中元素插入索引处,如果索引大于数组长度,则将在末尾插入。
这是我在一个应用程序中使用的一个工作函数。
这将检查项目是否存在:
let ifExist = (item, strings = [ '' ], position = 0) => {
// Output into an array with an empty string. Important just in case their isn't any item.
let output = [ '' ];
// Check to see if the item that will be positioned exist.
if (item) {
// Output should be equal to an array of strings.
output = strings;
// Use splice() in order to break the array.
// Use positional parameters to state where to put the item
// and 0 is to not replace an index. Item is the actual item we are placing at the prescribed position.
output.splice(position, 0, item);
}
// Empty string is so we do not concatenate with comma or anything else.
return output.join("");
};
然后我把它叫做下面。
ifExist("friends", [ ' ( ', ' )' ], 1)} // Output: ( friends )
ifExist("friends", [ ' - '], 1)} // Output: - friends
ifExist("friends", [ ':'], 0)} // Output: friends:
我不得不同意Redu的回答,因为splice()的界面确实有点混乱。cdbajorin给出的响应是“当第二个参数为0时,它只返回一个空数组。如果它大于0,则返回从数组中删除的项“虽然准确,但证明了这一点。
该功能的目的是拼接,或者如Jakob Keller先前所说,“连接或连接,也改变。
您有一个已建立的阵列,现在正在更改,这将涉及添加或删除元素。。。。“考虑到这一点,被删除的元素(如果有的话)的返回值充其量是尴尬的。我100%同意,如果该方法返回了一个看起来很自然的新数组,添加了拼接元素,则该方法可能更适合于链接。然后,您可以对返回的数组执行类似[”19“,”17“].splice(1,0,”18“).join(”…“)之类的操作。
它返回删除的内容这一事实简直是无稽之谈。如果该方法的目的是“删除一组元素”,而这是它唯一的目的,也许。似乎如果我不知道我已经剪了什么,我可能没有什么理由剪掉这些元素,不是吗?
如果它表现得像concat()、map()、reduce()、slice()等,从现有数组生成新数组,而不是改变现有数组,那会更好。这些都是可链接的,这是一个重要的问题。链数组操作非常常见。
似乎语言需要朝一个或另一个方向发展,并尽可能地坚持下去。JavaScript具有功能性,声明性较低,这似乎是一种与规范的奇怪偏差。
有两种方法:
const array=['My','name','Hamza'];array.拼接(2,0,'is');console.log(“方法1:”,array.join(“”));
Or
Array.prototype.insert=函数(索引,项){此.拼接(索引,0,项);};const array=['My','name','Hamza'];array.insert(2,'is');console.log(“方法2:”,array.join(“”));
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)];
解决方案和性能
今天(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上一个小数组的示例结果如下:
不可变插入
如果您需要插入到阵列中的适当位置,使用拼接方法无疑是最佳答案。
但是,如果您正在寻找一个不可变函数,该函数返回一个新的更新数组,而不是在插入时对原始数组进行变异,那么可以使用以下函数。
函数插入(数组,索引){const items=Array.prototype.slice.call(arguments,2);return[].contat(array.sslice(0,索引),items,array.sslict(索引));}常量列表=['one','two','three'];const list1=插入(列表,0,“零”);//插入单个项目const list2=insert(列表,3,'four','five','sive');//插入多个console.log('原始列表:',列表);console.log('插入的列表1:',列表1);console.log('插入的列表2:',列表2);
注意:这是ES6之前的一种实现方式,因此它适用于较旧和较新的浏览器。
如果您使用的是ES6,那么您也可以尝试其他参数;看看这个答案。
我喜欢一点安全,我用这个:
Array.prototype.Insert=函数(项,之前){if(!item)返回;if(before==null|| before<0|| before>this.length-1){this.push(项目);回来}此.拼接(之前,0,项);}var t=[“a”,“b”]t.插入(“v”,1)控制台日志(t)
以下是现代(字体功能)方式:
export const insertItemInList = <T>(
arr: T[],
index: number,
newItem: T
): T[] => [...arr.slice(0, index), newItem, ...arr.slice(index)]
使用Array.prototype.splice()是实现它的一种简单方法
常量数=[“一”、“二”、“四”、“五”]数字拼接(2,0,“三”);console.log(数字)
阅读有关Array.prototype.splice的更多信息
您可以使用splice()进行此操作
splice()方法在添加元素时通常会收到三个参数:
要添加项的数组的索引。要删除的项目数,在本例中为0。要添加的元素。
let array=['item 1','item 2','item 3']让insertAtIndex=0let itemsToRemove=0array.spling(insertAtIndex,itemsToRemove,'在索引0上插入此字符串')console.log(数组)
我这样做:
const insert = (what, where, index) =>
([...where.slice(0, index), what , ...where.slice(index, where.length)]);
常量插入=(what,where,index)=>([…where.slice(0,index),what,…where.slice(index,where.length)]);常量列表=[1,2,3,4,5,6];const newList=插入('a',列表,2);console.log(newList.indexOf('a')==2);
下面是一个支持同时插入多个值的简单函数:
function add_items_to_array_at_position(array, index, new_items)
{
return [...array.slice(0, index), ...new_items, ...array.slice(index)];
}
用法示例:
let old_array = [1,2,5];
let new_array = add_items_to_array_at_position(old_array, 2, [3,4]);
console.log(new_array);
//Output: [1,2,3,4,5]
var array= [10,20,30,40]
var i;
var pos=2; //pos=index + 1
/*pos is position which we want to insert at which is index + 1.position two in an array is index 1.*/
var value=5
//value to insert
//Initialize from last array element
for(i=array.length-1;i>=pos-1;i--){
array[i+1]=array[i]
}
array[pos-1]=value
console.log(array)
您可以使用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);;
}
阵列切片的文档
多用途ARRAY和ARRAY OF OBJECT可重用方法
设arr=[0,1,2];让obj=〔{name:“abc”},{name::“xyz”};const addArrayItemAtIndex=(数组,索引,newItem)=>{return[…array.sslice(0,索引),newItem,…array.sSlice(索引)];}//对于阵列console.log(addArrayItemAtIndex(arr,2159));//对于对象阵列console.log(addArrayItemAtIndex(obj,0,{name:“AMOS”}));