Sto cercando un metodo di inserimento di array JavaScript, nello stile di:
arr.insert(index, item)
Preferibilmente in jQuery, ma qualsiasi implementazione JavaScript andrà bene a questo punto.
Sto cercando un metodo di inserimento di array JavaScript, nello stile di:
arr.insert(index, item)
Preferibilmente in jQuery, ma qualsiasi implementazione JavaScript andrà bene a questo punto.
Risposte:
Quello che vuoi è la splice
funzione sull'oggetto array nativo.
arr.splice(index, 0, item);
inserirà item
in arr
corrispondenza dell'indice specificato (cancellando 0
oggetti prima, cioè, è solo un inserto).
In questo esempio creeremo un array e aggiungeremo un elemento ad esso nell'indice 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)
rimuoverà 3 elementi a partire dall'indice 2. Senza passare il 3 ° .... N ° parametro non viene inserito nulla. Quindi insert()
neanche il nome rende giustizia.
È possibile implementare il Array.insert
metodo in questo modo:
Array.prototype.insert = function ( index, item ) {
this.splice( index, 0, item );
};
Quindi puoi usarlo come:
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)); }
Oltre alla giunzione, è possibile utilizzare questo approccio che non modificherà l'array originale, ma creerà un nuovo array con l'elemento aggiunto. Di solito dovresti evitare la mutazione quando possibile. Sto usando l'operatore di diffusione ES6 qui.
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]
Questo può essere usato per aggiungere più di un articolo modificando un po 'la funzione per utilizzare l'operatore di riposo per i nuovi articoli e diffonderlo anche nel risultato restituito
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
Metodi di array personalizzati/* 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;
};
Può inserire più elementi (come splice
fa nativo ) e supporta il concatenamento:
["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;
};
Può unire gli array dagli argomenti con l'array specificato e supporta anche il concatenamento:
["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"]
. Perché non è "d"
incluso? Mi sembra che se si inserisce 6 come secondo parametro di slice()
e vi sono 6 elementi nell'array a partire dall'indice specificato, è necessario ottenere tutti e 6 gli elementi nel valore restituito. (Il documento dice howMany
per quel parametro.) Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3);
=>[ ]
slice
metodo e non splice
, a cui ti riferisci nel commento. Il secondo parametro di slice
(denominato end
) è un indice a base zero in corrispondenza del quale terminare l'estrazione. slice
estrae fino a ma non compresoend
. Quindi dopo insert
che hai ["a", "b", "X", "Y", "Z", "c", "d"]
, da cui slice
estrae elementi con indici da 1
fino a 6
, cioè da "b"
a "d"
ma non inclusi "d"
. Ha senso?
Se vuoi inserire più elementi contemporaneamente in un array, dai un'occhiata a questa risposta di Stack Overflow: un modo migliore per unire un array in un array in javascript
Anche qui ci sono alcune funzioni per illustrare entrambi gli esempi:
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;
}
Finalmente ecco un jsFiddle in modo da poterlo vedere da soli: http://jsfiddle.net/luisperezphd/Wc8aS/
Ed è così che usi le funzioni:
// 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);
Per una corretta programmazione funzionale e scopi di concatenamento Array.prototype.insert()
è essenziale un'invenzione di . In realtà la giuntura avrebbe potuto essere perfetta se avesse restituito la matrice mutata invece di una matrice vuota totalmente priva di significato. Quindi eccolo qui
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>");
Bene ok quanto sopra con Array.prototype.splice()
quello che muta l'array originale e alcuni potrebbero lamentarsi come "non dovresti modificare ciò che non ti appartiene" e questo potrebbe rivelarsi giusto. Quindi per il benessere pubblico vorrei dare un altro Array.prototype.insert()
che non muta l'array originale. Eccolo;
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
muta l'array originale, non credo che la "corretta programmazione funzionale" appartenga ovunque nelle vicinanze di splice
.
Ti consiglio di usare JavaScript puro in questo caso, inoltre non esiste un metodo di inserimento in JavaScript, ma abbiamo un metodo che è un metodo Array integrato che fa il lavoro per te, si chiama splice ...
Vediamo cos'è splice () ...
Il metodo splice () modifica il contenuto di un array rimuovendo elementi esistenti e / o aggiungendo nuovi elementi.
OK, immagina di avere questo array qui sotto:
const arr = [1, 2, 3, 4, 5];
Possiamo rimuovere in 3
questo modo:
arr.splice(arr.indexOf(3), 1);
Restituirà 3, ma se controlliamo arr ora, abbiamo:
[1, 2, 4, 5]
Fin qui tutto bene, ma come possiamo aggiungere un nuovo elemento all'array usando splice? Rimettiamo 3 in arr ...
arr.splice(2, 0, 3);
Vediamo cosa abbiamo fatto ...
Usiamo di nuovo splice , ma questa volta per il secondo argomento, passiamo 0 , significa che non vogliamo eliminare alcun elemento, ma allo stesso tempo, aggiungiamo il terzo argomento che è 3 che verrà aggiunto al secondo indice ...
Dovresti essere consapevole del fatto che possiamo eliminare e aggiungere contemporaneamente, ad esempio ora possiamo fare:
arr.splice(2, 2, 3);
Che eliminerà 2 elementi all'indice 2, quindi aggiungerà 3 all'indice 2 e il risultato sarà:
[1, 2, 3, 5];
Questo mostra come funziona ogni elemento nella giunzione:
array.splice (start, deleteCount, item1, item2, item3 ...)
Aggiungi elemento singolo a un indice specifico
//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';
Aggiungi più elementi a un indice specifico
//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';
aggiungerà se l'array ha solo 3 elementi. Se è presente un elemento nell'indice 3, questo verrà sostituito. Se vuoi aggiungere alla fine, è meglio usarearrName.push('newName1');
Un'altra possibile soluzione, con l'utilizzo di 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);
Ecco due modi:
const array = [ 'My', 'name', 'Hamza' ];
array.splice(2, 0, 'is');
console.log("Method 1 : ", array.join(" "));
O
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(" "));
Anche se è già stata data una risposta, sto aggiungendo questa nota per un approccio alternativo.
Volevo posizionare un numero noto di elementi in un array, in posizioni specifiche, poiché escono da un "array associativo" (cioè un oggetto) che per definizione non è garantito che sia in un ordine ordinato. Volevo che l'array risultante fosse un array di oggetti, ma gli oggetti fossero in un ordine specifico nell'array poiché un array garantisce il loro ordine. Quindi l'ho fatto.
Innanzitutto l'oggetto sorgente, una stringa JSONB recuperata da PostgreSQL. Volevo ordinarlo in base alla proprietà "order" in ogni oggetto figlio.
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);
Poiché il numero di nodi nell'oggetto è noto, per prima cosa creo un array con la lunghezza specificata:
var obj_length = Object.keys(jsonb_obj).length;
var sorted_array = new Array(obj_length);
E quindi iterare l'oggetto, posizionando gli oggetti temporanei appena creati nelle posizioni desiderate dell'array senza realmente aver luogo alcun "ordinamento".
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);
Chiunque abbia ancora problemi con questo e abbia provato tutte le opzioni sopra e non l'abbia mai ottenuto. Sto condividendo la mia soluzione, questo è per prendere in considerazione che non vuoi dichiarare esplicitamente le proprietà del tuo oggetto rispetto alla matrice.
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;
}
Questa è una combinazione di iterare l'array di riferimento e confrontarlo con l'oggetto che si desidera verificare, convertirli entrambi in una stringa e quindi iterare se corrisponde. Quindi puoi solo contare. Questo può essere migliorato, ma è qui che mi sono sistemato. Spero che sia di aiuto.
Approfittando del metodo di riduzione come segue:
function insert(arr, val, index) {
return index >= arr.length
? arr.concat(val)
: arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
}
Quindi in questo modo possiamo restituire un nuovo array (sarà un modo funzionale interessante - molto meglio dell'uso push o splice) con l'elemento inserito all'indice e se l'indice è maggiore della lunghezza dell'array verrà inserito alla fine.
Array#splice()
è la strada da percorrere, a meno che tu non voglia davvero evitare di mutare l'array. Dati 2 array arr1
e arr2
, ecco come inserire il contenuto arr2
in arr1
dopo il primo elemento:
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)
Se sei preoccupato di mutare l'array (ad esempio, se usi Immutable.js), puoi invece usare slice()
, da non confondere con splice()
a 'p'
.
const arr3 = [...arr1.slice(0, 1), ...arr2, ...arr1.slice(1)];
Ho provato questo e funziona benissimo!
var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);
Indice è la posizione in cui si desidera inserire o eliminare l'elemento. 0 vale a dire che il secondo parametro definisce il numero di elementi dall'indice da rimuovere. Sono le nuove voci che si desidera creare nella matrice. Può essere uno o più di uno.
initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
Ecco una funzione funzionante che utilizzo in una mia applicazione.
Questo controlla se l'oggetto esce
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("");
};
E poi lo chiamo di seguito.
ifExist("friends", [ ' ( ', ' )' ], 1)} // output: ( friends )
ifExist("friends", [ ' - '], 1)} // output: - friends
ifExist("friends", [ ':'], 0)} // output: friends:
Un po 'più vecchio, ma devo concordare con Redu sopra perché splice ha sicuramente un'interfaccia un po' confusa. E la risposta data da cdbajorin che "restituisce un array vuoto solo quando il secondo parametro è 0. Se è maggiore di 0, restituisce gli elementi rimossi dall'array" sta dimostrando il punto, sebbene accurato. L'intento della funzione è di giuntare o come detto in precedenza da Jakob Keller, "di unirsi o connettersi, anche per cambiare. Hai un array consolidato che stai cambiando che implicherebbe l'aggiunta o la rimozione di elementi ...." Dato che, il il valore di ritorno degli eventuali elementi che sono stati rimossi è nella migliore delle ipotesi scomodo. E concordo al 100% che questo metodo avrebbe potuto essere più adatto al concatenamento se avesse restituito ciò che sembra naturale, un nuovo array con gli elementi giuntati aggiunti. Quindi potresti fare cose come ["19", "17"]. Splice (1,0, "18"). Join ("...") o qualunque cosa ti piaccia con l'array restituito. Il fatto che restituisca ciò che è stato rimosso è solo un po 'senza senso IMHO. Se l'intenzione del metodo era di "ritagliare un insieme di elementi" e quello era solo l'intento, forse. Sembra che se non sapessi già cosa tagliare, probabilmente ho poche ragioni per ritagliarli, no? Sarebbe meglio se si comportasse come concat, map, ridurre, slice, ecc. Dove un nuovo array viene creato dall'array esistente piuttosto che mutare l'array esistente. Questi sono tutti incatenabili e questo è un problema significativo. È piuttosto comune alla manipolazione di array di catene. Sembra che la lingua debba andare in una direzione o nell'altra e cercare di attenersi il più possibile. Essendo Javascript funzionale e meno dichiarativo, sembra solo una strana deviazione dalla norma.
Oggi (2020.04.24) eseguo test per soluzioni scelte per array grandi e piccoli. Li ho testati su MacO High Sierra 10.13.6 su Chrome 81.0, Safari 13.1, Firefox 75.0.
Per tutti i browser
slice
e reduce
(D, E, F) sono in genere 10x-100x più veloci delle soluzioni sul postosplice
(AI, BI, CI) sono state le più veloci (a volte ~ 100x - ma dipende dalle dimensioni dell'array)I test sono stati divisi in due gruppi: soluzioni sul posto (AI, BI, CI) e soluzioni non sul posto (D, E, F) e sono state eseguite per due casi
Il codice testato è presentato nello snippet di seguito
Di seguito sono riportati i risultati di esempio per array di piccole dimensioni su Chrome