Szukam metody wstawiania tablic JavaScript w stylu:
arr.insert(index, item)
Najlepiej w jQuery, ale w tym momencie zrobi to każda implementacja JavaScript.
Szukam metody wstawiania tablic JavaScript w stylu:
arr.insert(index, item)
Najlepiej w jQuery, ale w tym momencie zrobi to każda implementacja JavaScript.
Odpowiedzi:
To, czego chcesz, to splice
funkcja w natywnym obiekcie tablicowym.
arr.splice(index, 0, item);
wstawi item
się arr
pod określonym indeksem ( 0
najpierw usuwając elementy, to znaczy, to tylko wstawka).
W tym przykładzie utworzymy tablicę i dodamy do niej element do indeksu 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());
arr.splice(2,3)
usunie 3 elementy, zaczynając od indeksu 2. Bez przekazania 3. .... N-tych parametrów nic nie zostanie wstawione. Więc nazwa insert()
też nie oddaje sprawiedliwości.
Możesz zaimplementować Array.insert
metodę, wykonując następujące czynności:
Array.prototype.insert = function ( index, item ) {
this.splice( index, 0, item );
};
Następnie możesz użyć go w następujący sposób:
var arr = [ 'A', 'B', 'D', 'E' ];
arr.insert(2, 'C');
// => arr == [ 'A', 'B', 'C', 'D', 'E' ]
Array.prototype.insert = function (index, items) { this.splice.apply(this, [index, 0].concat(items)); }
Inne niż połączenie, możesz użyć tego podejścia, które nie spowoduje mutacji oryginalnej tablicy, ale utworzy nową tablicę z dodanym elementem. Zazwyczaj należy unikać mutacji, gdy tylko jest to możliwe. Używam tutaj operatora rozprzestrzeniania 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]
Można tego użyć, aby dodać więcej niż jeden element, nieco poprawiając funkcję, aby użyć operatora spoczynkowego dla nowych elementów i rozłożyć to również na zwracany wynik
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]
insert
metody tablicowe/* 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;
};
Może wstawiać wiele elementów (podobnie jak natywny splice
) i obsługuje tworzenie łańcuchów:
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6);
// ["b", "X", "Y", "Z", "c"]
/* 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;
};
Może łączyć tablice z argumentów z podaną tablicą, a także obsługuje łańcuch:
["a", "b", "c", "d"].insert(2, "V", ["W", "X", "Y"], "Z").join("-");
// "a-b-V-W-X-Y-Z-c-d"
["b", "X", "Y", "Z", "c"]
. Dlaczego nie jest "d"
uwzględniony? Wydaje mi się, że jeśli wstawisz 6 jako drugi parametr slice()
i w tablicy jest 6 elementów zaczynających się od określonego indeksu, to powinieneś otrzymać wszystkie 6 elementów w wartości zwracanej. (Dokument mówi howMany
o tym parametrze.) Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3);
=>[ ]
slice
metody, a nie splice
, o której mówisz w komentarzu. Drugi parametr slice
(o nazwie end
) to liczony od zera indeks, przy którym kończy się ekstrakcja. slice
wyciągi do, ale nie w tymend
. Stąd po insert
masz ["a", "b", "X", "Y", "Z", "c", "d"]
, z którego slice
wyodrębnia się elementy z indeksami od 1
do 6
, tj. Od "b"
do, "d"
ale bez uwzględnienia "d"
. Czy ma sens?
Jeśli chcesz wstawić wiele elementów do tablicy jednocześnie, sprawdź odpowiedź Przepełnienie stosu: Lepszy sposób na podzielenie tablicy na tablicę w javascript
Oto niektóre funkcje ilustrujące oba przykłady:
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;
}
Nareszcie jest jsFiddle, więc możesz to zobaczyć na własne oczy: http://jsfiddle.net/luisperezphd/Wc8aS/
I w ten sposób korzystasz z funkcji:
// 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);
Dla właściwego programowania funkcjonalnego i tworzenia łańcuchów Array.prototype.insert()
niezbędny jest wynalazek . W rzeczywistości splot mógłby być idealny, gdyby zwrócił zmutowaną tablicę zamiast całkowicie pozbawionej znaczenia pustej tablicy. Więc proszę
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>");
Cóż, ok powyższe z tym Array.prototype.splice()
mutuje oryginalną tablicę, a niektórzy mogą narzekać: „nie powinieneś modyfikować tego, co nie należy do ciebie”, co również może okazać się słuszne. Więc dla dobra publicznego chciałbym podać inny, Array.prototype.insert()
który nie mutuje oryginalnej tablicy. Oto jest;
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));
splice
mutujesz oryginalną tablicę, nie sądzę, aby „właściwe programowanie funkcjonalne” należało do dowolnego miejsca w pobliżu splice
.
W tym przypadku zalecam użycie czystego JavaScript , nie ma też metody wstawiania w JavaScript, ale mamy metodę, która jest wbudowaną metodą Array , która wykonuje zadanie za Ciebie, nazywa się to splice ...
Zobaczmy, co jest splice () ...
Metoda splice () zmienia zawartość tablicy poprzez usunięcie istniejących elementów i / lub dodanie nowych elementów.
OK, wyobraź sobie, że mamy tę tablicę poniżej:
const arr = [1, 2, 3, 4, 5];
Możemy usunąć w 3
następujący sposób:
arr.splice(arr.indexOf(3), 1);
Zwróci 3, ale jeśli teraz sprawdzimy ARR, otrzymamy:
[1, 2, 4, 5]
Jak dotąd tak dobrze, ale jak możemy dodać nowy element do tablicy za pomocą splice? Odłóżmy 3 do arr ...
arr.splice(2, 0, 3);
Zobaczmy, co zrobiliśmy ...
Ponownie używamy splajnu , ale tym razem dla drugiego argumentu przekazujemy 0 , co oznacza, że nie chcemy usuwać żadnego elementu, ale jednocześnie dodajemy trzeci argument, czyli 3, który zostanie dodany przy drugim indeksie ...
Należy pamiętać, że możemy jednocześnie usuwać i dodawać , na przykład teraz możemy:
arr.splice(2, 2, 3);
Co spowoduje usunięcie 2 elementów z indeksu 2, a następnie dodanie 3 z indeksu 2, a wynikiem będzie:
[1, 2, 3, 5];
To pokazuje, jak działa każdy element w połączeniu:
array.splice (start, deleteCount, item1, item2, item3 ...)
Dołącz pojedynczy element do określonego indeksu
//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';
Dołącz wiele elementów do określonego indeksu
//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
arrName[3] = 'newName1';
zostanie dołączona, jeśli tablica zawiera tylko 3 elementy. Jeśli w indeksie 3 znajduje się element, zostanie on zastąpiony. Jeśli chcesz dołączyć na końcu, lepiej użyćarrName.push('newName1');
Inne możliwe rozwiązanie z wykorzystaniem 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);
Oto dwa sposoby:
const array = [ 'My', 'name', 'Hamza' ];
array.splice(2, 0, 'is');
console.log("Method 1 : ", array.join(" "));
LUB
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(" "));
Mimo że już na to odpowiedziano, dodaję tę notatkę dla alternatywnego podejścia.
Chciałem umieścić znany numer elementów w tablicy, w określonych pozycjach, ponieważ wychodzą one z „tablicy asocjacyjnej” (tj. Obiektu), który z definicji nie ma zagwarantowanej kolejności. Chciałem, aby wynikowa tablica była tablicą obiektów, ale obiekty powinny być w określonej kolejności w tablicy, ponieważ tablica gwarantuje ich kolejność. Więc to zrobiłem.
Najpierw obiekt źródłowy, ciąg JSONB pobrany z PostgreSQL. Chciałem, aby została posortowana według właściwości „order” w każdym obiekcie potomnym.
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);
Ponieważ liczba węzłów w obiekcie jest znana, najpierw tworzę tablicę o określonej długości:
var obj_length = Object.keys(jsonb_obj).length;
var sorted_array = new Array(obj_length);
A następnie iteruj obiekt, umieszczając nowo utworzone obiekty tymczasowe w pożądanych lokalizacjach w tablicy, bez faktycznego „sortowania”.
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);
Każdy, kto nadal ma problemy z tym i wypróbował wszystkie powyższe opcje i nigdy go nie otrzymał. Dzielę się moim rozwiązaniem, aby wziąć pod uwagę, że nie chcesz wyraźnie określać właściwości obiektu względem tablicy.
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;
}
Jest to kombinacja iteracji tablicy referencyjnej i porównania jej z obiektem, który chciałbyś sprawdzić, przekonwertować oba z nich na ciąg, a następnie iterować, jeśli pasuje. Wtedy możesz po prostu liczyć. Można to poprawić, ale tam się osiedliłem. Mam nadzieję że to pomoże.
Biorąc zysk z metody redukcji w następujący sposób:
function insert(arr, val, index) {
return index >= arr.length
? arr.concat(val)
: arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
}
W ten sposób możemy zwrócić nową tablicę (będzie to fajny sposób funkcjonalny - znacznie lepszy niż użycie push lub splice) z elementem wstawionym w indeksie, a jeśli indeks jest większy niż długość tablicy, zostanie wstawiony na końcu.
Array#splice()
jest właściwą drogą, chyba że naprawdę chcesz uniknąć mutacji tablicy. Biorąc pod uwagę 2 tablice arr1
i arr2
, oto jak można wstawić zawartość arr2
do arr1
po pierwszym elemencie:
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)
Jeśli obawiasz się o mutacji tablicę (na przykład w przypadku korzystania Immutable.js), można zamiast tego użyć slice()
, nie należy mylić z splice()
z 'p'
.
const arr3 = [...arr1.slice(0, 1), ...arr2, ...arr1.slice(1)];
Próbowałem tego i działa dobrze!
var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);
Indeks to pozycja, w której chcesz wstawić lub usunąć element. 0 tzn. Drugie parametry definiują liczbę elementów z indeksu do usunięcia. Pozycjami są nowe wpisy, które chcesz wprowadzić w tablicy. Może to być jeden lub więcej niż jeden.
initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
Oto działająca funkcja, której używam w jednej z moich aplikacji.
Sprawdza to, czy produkt wyjdzie
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("");
};
A potem nazywam to poniżej.
ifExist("friends", [ ' ( ', ' )' ], 1)} // output: ( friends )
ifExist("friends", [ ' - '], 1)} // output: - friends
ifExist("friends", [ ':'], 0)} // output: friends:
Trochę starszego wątku, ale muszę się zgodzić z Redu powyżej, ponieważ splice zdecydowanie ma nieco mylący interfejs. A odpowiedź udzielona przez cdbajorin, że „zwraca pustą tablicę tylko wtedy, gdy drugim parametrem jest 0. Jeśli jest większa niż 0, zwraca elementy usunięte z tablicy”, choć jest dokładna, potwierdza to. Funkcja ma na celu splatanie lub, jak powiedział wcześniej Jakob Keller, „łączyć się lub łączyć, a także zmieniać. Masz ustaloną tablicę, którą teraz zmieniasz, co wymagałoby dodawania lub usuwania elementów ...” Biorąc pod uwagę, że wartość zwracana elementów, które zostały usunięte, jest co najwyżej niewygodna. I w 100% zgadzam się, że ta metoda mogłaby być lepiej dostosowana do tworzenia łańcuchów, gdyby zwróciła coś, co wydaje się naturalne, nową tablicę z dodanymi połączonymi elementami. Następnie możesz robić rzeczy takie jak [„19”, „17”]. Splice (1,0, „18”). Łączyć („...”) lub cokolwiek zechcesz ze zwróconą tablicą. Fakt, że zwraca to, co zostało usunięte, jest po prostu nonsensem IMHO. Jeśli celem tej metody było „wycięcie zestawu elementów”, a może tylko taka była intencja. Wygląda na to, że jeśli nie wiem, co już wycinam, prawdopodobnie nie mam powodu, by wycinać te elementy, prawda? Byłoby lepiej, gdyby zachowywał się jak konkatacja, mapa, redukcja, plaster itp., Gdzie nowa tablica jest tworzona z istniejącej tablicy, zamiast mutować istniejącą tablicę. Wszystkie są zbywalne i jest to poważny problem. Raczej manipulowanie łańcuchem tablicowym jest dość powszechne. Wygląda na to, że język musi podążać w jednym lub drugim kierunku i starać się go trzymać w jak największym stopniu. JavaScript jest funkcjonalny i mniej deklaratywny, wydaje się po prostu dziwnym odstępstwem od normy.
Dzisiaj (2020.04.24) wykonuję testy dla wybranych rozwiązań dla dużych i małych macierzy. Testowałem je na MacOs High Sierra 10.13.6 na Chrome 81.0, Safari 13.1, Firefox 75.0.
Dla wszystkich przeglądarek
slice
i reduce
(D, E, F) są zwykle 10 x 100 razy szybsze niż rozwiązania na miejscusplice
(AI, BI, CI) były najszybsze (czasami ~ 100x - ale zależy to od rozmiaru tablicy)Testy podzielono na dwie grupy: rozwiązania na miejscu (AI, BI, CI) i rozwiązania na miejscu (D, E, F) i przeprowadzono je w dwóch przypadkach
Testowany kod jest przedstawiony poniżej
Przykładowe wyniki dla małej tablicy na chrome są poniżej