Я ищу метод вставки массива JavaScript, в стиле:

arr.insert(index, item)

Желательно в jQuery, но любая реализация JavaScript подойдет на этом этапе.

3242
tags2k 25 Фев 2009 в 17:29

17 ответов

Лучший ответ

Вам нужен splice Функция для собственного объекта массива.

arr.splice(index, 0, item); вставит item в arr по указанному индексу (сначала удаляются 0 элементы, то есть это просто вставка).

В этом примере мы создадим массив и добавим элемент в индекс 2:

var arr = [];
arr[0] = "Jani";
arr[1] = "Hege";
arr[2] = "Stale";
arr[3] = "Kai Jim";
arr[4] = "Borge";

console.log(arr.join());
arr.splice(2, 0, "Lene");
console.log(arr.join());
4611
Zze 24 Апр 2018 в 11:03

Взятие прибыли по методу снижения следующим образом:

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) с элементом, вставленным в index, и, если индекс больше длины массива, он будет вставлен в конце.

3
alejoko 12 Янв 2019 в 17:04

Добавить отдельный элемент по определенному индексу

//Append at 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 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
13
Ryan Taylor 19 Июл 2018 в 13:20

Если вы хотите вставить несколько элементов в массив одновременно, проверьте ответ о переполнении стека: Лучший способ объединить массив в массив в 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);
40
Community 23 Май 2017 в 12:10

Хотя на этот вопрос уже дан ответ, я добавляю эту заметку для альтернативного подхода.

Я хотел поместить известное число элементов в массив, в определенные позиции, так как они выходят из «ассоциативного массива» (то есть объекта), который по определению не гарантированно находится в отсортированном заказ. Я хотел, чтобы результирующий массив был массивом объектов, но объекты должны быть в определенном порядке в массиве, так как массив гарантирует их порядок. Я так и сделал.

Сначала исходный объект, строка JSONB, полученная из PostgreSQL. Я хотел отсортировать его по свойству 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);
4
K.Dᴀᴠɪs 30 Мар 2018 в 21:26

Помимо сращивания, вы можете использовать этот подход, который не будет изменять исходный массив, но создаст новый массив с добавленным элементом. Обычно вы должны избегать мутаций, когда это возможно. Я использую ES6 спред оператора здесь.

const items = [1, 2, 3, 4, 5]

const insert = (arr, index, newItem) => [
  // part of the array before the specified index
  ...arr.slice(0, index),
  // inserted item
  newItem,
  // part of the array after the specified index
  ...arr.slice(index)
]

const result = insert(items, 1, 10)

console.log(result)
// [1, 10, 2, 3, 4, 5]

Это можно использовать для добавления более одного элемента, немного подправив функцию, чтобы использовать оператор rest для новых элементов, и распространить ее в возвращаемом результате.

const items = [1, 2, 3, 4, 5]

const insert = (arr, index, ...newItems) => [
  // part of the array before the specified index
  ...arr.slice(0, index),
  // inserted items
  ...newItems,
  // part of the array after the specified index
  ...arr.slice(index)
]

const result = insert(items, 1, 10, 20)

console.log(result)
// [1, 10, 20, 2, 3, 4, 5]
129
gafi 4 Июл 2016 в 09:18

Array#splice() - это путь, если вы действительно не хотите избегать мутаций массив. Учитывая 2 массива arr1 и arr2, вот как вы должны вставить содержимое arr2 в arr1 после первого элемента:


const arr1 = ['a', 'd', 'e'];
const arr2 = ['b', 'c'];

arr1.splice(1, 0, ...arr2); // arr1 now contains ['a', 'b', 'c', 'd', 'e']

console.log(arr1)

Если вас беспокоит изменение массива (например, при использовании Immutable.js), вы можете вместо этого использовать slice(), не путать с splice() с 'p'.

const arr3 = [...arr1.slice(0, 1), ...arr2, ...arr1.slice(1)];
2
Dipen 7 Фев 2020 в 11:34

Вы можете реализовать метод Array.insert, выполнив это:

Array.prototype.insert = function ( index, item ) {
    this.splice( index, 0, item );
};

Тогда вы можете использовать его как:

var arr = [ 'A', 'B', 'D', 'E' ];
arr.insert(2, 'C');

// => arr == [ 'A', 'B', 'C', 'D', 'E' ]
279
K.Dᴀᴠɪs 30 Мар 2018 в 21:26

Вот два способа:

const array = [ 'My', 'name', 'Hamza' ];

array.splice(2, 0, 'is');

console.log("Method 1 : ", array.join(" "));

< Сильный > ИЛИ

Array.prototype.insert = function ( index, item ) {
    this.splice( index, 0, item );
};

const array = [ 'My', 'name', 'Hamza' ];
array.insert(2, 'is');

console.log("Method 2 : ", array.join(" "));
5
M. Hamza Rajput 28 Авг 2019 в 09:28

Другое возможное решение с использованием Array#reduce.

var arr = ["apple", "orange", "raspberry"],
    arr2 = [1, 2, 4];

function insert(arr, item, index) {
    arr = arr.reduce(function(s, a, i) {
      i == index ? s.push(item, a) : s.push(a);
      return s;
    }, []);   
    console.log(arr);
}

insert(arr, "banana", 1);
insert(arr2, 3, 2);
6
kind user 5 Апр 2017 в 17:06

Я рекомендую использовать чистый JavaScript в этом случае, также в JavaScript нет метода вставки, но у нас есть метод, который является встроенным методом Array , который выполняет работу для вы, это называется сплайс ...

Давайте посмотрим, что такое splice () ...

Метод splice () изменяет содержимое массива, удаляя существующие элементы и / или добавляя новые элементы.

Хорошо, представьте, что у нас есть этот массив ниже:

const arr = [1, 2, 3, 4, 5];

Мы можем удалить 3 следующим образом:

arr.splice(arr.indexOf(3), 1);

Он вернет 3, но если мы проверим arr сейчас, мы имеем:

[1, 2, 4, 5]

Пока все хорошо, но как мы можем добавить новый элемент в массив, используя соединение? Давайте вернем 3 в обр ...

arr.splice(2, 0, 3);

Посмотрим, что мы сделали ...

Мы снова используем сплайс , но на этот раз для второго аргумента мы передаем 0 , что означает, что мы не хотим удалять элементы, но в то же время мы добавляем третий аргумент, который 3 будет добавлено во второй индекс ...

Вы должны знать, что мы можем удалить и добавить одновременно, например, теперь мы можем сделать:

arr.splice(2, 2, 3);

Который удалит 2 элемента в индексе 2, затем добавит 3 в индекс 2, и результат будет:

[1, 2, 3, 5];

Это показывает, как работает каждый элемент в соединении:

array.splice (start, deleteCount, item1, item2, item3 ...)

17
Alireza 12 Июл 2018 в 05:49

Я попробовал это, и он работает нормально!

var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);

Индекс - это позиция, в которую вы хотите вставить или удалить элемент. 0 то есть вторые параметры определяют количество элементов из индекса, подлежащего удалению. Элемент - это новые записи, которые вы хотите сделать в массиве. Это может быть один или несколько.

initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
2
K.Dᴀᴠɪs 30 Мар 2018 в 21:27

Любой, у кого все еще есть проблемы с этим и попробовал все варианты выше и никогда не получил это. Я поделюсь своим решением, это принять во внимание, что вы не хотите явно указывать свойства вашего объекта против массива.

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;
}

Это комбинация итерации эталонного массива и сравнения его с объектом, который вы хотите проверить, преобразовать их оба в строку, а затем повторить, если она совпадает. Тогда вы можете просто посчитать. Это можно улучшить, но это то, где я остановился. Надеюсь это поможет.

3
Clyde 6 Дек 2018 в 04:26

Пользовательский массив insert методов

< Ет > 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;
};

Он может вставлять несколько элементов (например, splice делает) и поддерживает создание цепочек:

["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6);
// ["b", "X", "Y", "Z", "c"]

< EM> 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/

76
VisioN 5 Апр 2013 в 16:44

Немного более старая тема, но я должен согласиться с Реду выше, потому что у splice определенно немного запутанный интерфейс. И ответ, данный cdbajorin, что «он возвращает пустой массив только тогда, когда второй параметр равен 0. Если он больше 0, он возвращает элементы, удаленные из массива», является точным доказательством этого. Функция предназначена для соединения или, как уже было сказано ранее, Якоба Келлера, «для присоединения или подключения, а также для изменения. У вас есть установленный массив, который вы сейчас изменяете, который включает добавление или удаление элементов…». Учитывая это, Возвращаемое значение элементов, если они были удалены, в лучшем случае неудобно. И я на 100% согласен, что этот метод мог бы лучше подходить для цепочки, если бы он возвратил то, что кажется естественным, новый массив с добавленными элементами сращивания. Затем вы можете делать что-то вроде ["19", "17"]. Splice (1,0, "18"). Join ("...") или что угодно с возвращаемым массивом. Тот факт, что он возвращает то, что было удалено, является просто бессмысленным ИМХО. Если целью метода было «вырезать набор элементов», и это было только его намерением, может быть. Похоже, если я не знаю, что я уже вырезал, у меня, вероятно, нет особых причин вырезать эти элементы, не так ли? Было бы лучше, если бы он вел себя как concat, map, Reduce, Slice и т. Д., Где новый массив создавался из существующего массива, а не изменял существующий массив. Все они цепные, и это серьезная проблема. Довольно часто манипулирование цепочками массивов. Похоже, что язык должен идти в том или ином направлении и стараться придерживаться его как можно больше. Javascript, будучи функциональным и менее декларативным, просто кажется странным отклонением от нормы.

1
meem 18 Июл 2019 в 17:38

Для правильного функционального программирования и создания цепочек изобретение Array.prototype.insert() необходимо. На самом деле, сплайсинг мог бы быть идеальным, если бы он возвращал измененный массив вместо совершенно бессмысленного пустого массива. Так что здесь идет

Array.prototype.insert = function(i,...rest){
  this.splice(i,0,...rest)
  return this
}

var 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 = function(i,...rest){
  return this.slice(0,i).concat(rest,this.slice(i));
}

var a = [3,4,8,9],
    b = a.insert(2,5,6,7);
console.log(JSON.stringify(a));
console.log(JSON.stringify(b));
22
Redu 22 Май 2016 в 21:43

Вот рабочая функция, которую я использую в одном из своих приложений.

Это проверяет, если пункт выхода

let ifExist = (item, strings = [ '' ], position = 0) => {
     // output into an array with empty string. Important just in case their is no item. 
    let output = [ '' ];
    // check to see if the item that will be positioned exist.
    if (item) {
        // output should equal to array of strings. 
        output = strings;
       // use splice in order to break the array. 
       // use positition param 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: 
1
Lesly Revenge 16 Фев 2019 в 22:48