私は次のスタイルのJavaScript配列挿入メソッドを探しています:
arr.insert(index, item)
jQueryが望ましいですが、JavaScriptの実装はこの時点で行います。
私は次のスタイルのJavaScript配列挿入メソッドを探しています:
arr.insert(index, item)
jQueryが望ましいですが、JavaScriptの実装はこの時点で行います。
回答:
必要なのは、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());
arr.splice(2,3)
インデックス2で始まる3つの要素を削除します。3rd.... Nthパラメータを渡さないと、何も挿入されません。そのため、その名前insert()
は正義にもなりません。
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' ]
Array.prototype.insert = function (index, items) { this.splice.apply(this, [index, 0].concat(items)); }
スプライス以外に、元の配列を変更せずに、追加された項目で新しい配列を作成するこのアプローチを使用できます。通常、可能な限り突然変異を回避する必要があります。ここでは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]
insert
メソッド/* 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"]
/* 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/
["b", "X", "Y", "Z", "c"]
。なぜ"d"
含まれていないのですか?の2番目のパラメータとして6をslice()
指定し、指定されたインデックスから始まる配列に6つの要素がある場合、戻り値には6つの要素すべてが含まれるはずです。(DOCは言うhowMany
そのパラメータのため。)developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3);
=>[ ]
slice
メソッドではなくを使用splice
しました。slice
(名前付きend
)の2番目のパラメーターは、抽出を終了するゼロベースのインデックスです。slice
含まないものまで抽出しend
ます。したがって、後にinsert
あなたが持っている["a", "b", "X", "Y", "Z", "c", "d"]
、そこからslice
のインデックスを持つ要素を抽出し1
、最大6
のすなわち、"b"
に"d"
は含みません"d"
。それは意味がありますか?
複数の要素を配列に一度に挿入する場合は、このスタックオーバーフローの回答を確認してください: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.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));
splice
、元の配列を変更していることを考えると、「適切な関数型プログラミング」はの近くのどこにも属していないと思いますsplice
。
この場合は純粋なJavaScriptを使用することをお勧めします。JavaScriptには挿入メソッドもありませんが、組み込みのArrayメソッドであるスプライスと呼ばれる機能を備えたメソッドがあり ます。
splice()とは何かを見てみましょう...
splice()メソッドは、既存の要素を削除したり、新しい要素を追加したりして、配列の内容を変更します。
OK、以下の配列があるとします。
const arr = [1, 2, 3, 4, 5];
次の3
ように削除できます:
arr.splice(arr.indexOf(3), 1);
3が返されますが、arrを今チェックすると、次のようになります。
[1, 2, 4, 5]
これまでのところ、とても良いですが、spliceを使用して配列に新しい要素を追加するにはどうすればよいですか?3を到着地に戻しましょう...
arr.splice(2, 0, 3);
私たちが何をしたか見てみましょう...
もう一度スプライスを使用しますが、今回は2番目の引数として0を渡します。つまり、アイテムを削除しないことを意味しますが、同時に、3番目の引数である3を追加します。これは、2番目のインデックスに追加されます...
削除と追加を同時に行うことができることに注意してください。たとえば、次のようにできます。
arr.splice(2, 2, 3);
インデックス2で2つのアイテムを削除し、インデックス2で3を追加すると、結果は次のようになります。
[1, 2, 3, 5];
これは、スプライスの各アイテムがどのように機能するかを示しています。
array.splice(start、deleteCount、item1、item2、item3 ...)
特定のインデックスに単一要素を追加する
//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
arrName[3] = 'newName1';
は、配列に3つの要素しかない場合に追加します。インデックス3に要素がある場合、これは置き換えられます。最後に追加する場合は、使用することをお勧めしますarrName.push('newName1');
を使用した別の可能な解決策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);
2つの方法があります。
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(" "));
これはすでに回答されていますが、別のアプローチのためにこのメモを追加します。
既知の数の項目を配列、特定の位置に配置したかったのは、それらが「連想配列」(つまり、オブジェクト)から出てきたためです。これは、定義上、ソートされた順序であることが保証されていません。結果の配列はオブジェクトの配列にしたかったのですが、配列はオブジェクトの順序を保証するため、オブジェクトは配列内の特定の順序になっています。だから私はこれをやった。
まず、ソースオブジェクト、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);
これでまだ問題があり、上記のすべてのオプションを試して、それを決して得ていない人。私は自分の解決策を共有しています。これは、オブジェクトと配列のプロパティを明示的に述べたくないということを考慮に入れるためです。
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), []);
}
したがって、このようにして、インデックスに要素を挿入して新しい配列を返すことができます(クールな機能的な方法になります-プッシュやスプライスを使用するよりもはるかに優れています)。インデックスが配列の長さよりも大きい場合は、挿入されます最後に。
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)];
私はこれを試してみましたが、うまくいきます!
var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);
インデックスは、要素を挿入または削除する位置です。0、つまり2番目のパラメータは、削除するインデックスからの要素数を定義します。項目は、配列に作成する新しいエントリです。1つまたは複数にすることができます。
initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
これは、私のアプリケーションの1つで使用する作業関数です。
アイテムが存在するかどうかを確認します
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:
少し古いスレッドですが、spliceには確かに少し混乱するインターフェースがあるため、上記のReduに同意する必要があります。そして、cdbajorinによって与えられた応答は、「2番目のパラメーターが0の場合にのみ空の配列を返します。0より大きい場合は、配列から削除された項目を返します」というのは正確ですが、要点です。関数の目的は、Jakob Kellerが先に述べたように、「結合または接続し、また変更することです。要素を追加または削除することを含む、現在変更中の確立された配列があります。」削除された要素の戻り値がある場合、それはせいぜいぎこちないです。そして、私はこの方法が、自然なように見えるもの、スプライスされた要素が追加された新しい配列を返した場合、連鎖にもっと適している可能性があることに100%同意します。次に、["19"、 "17"]。splice(1,0、 "18")。join( "...")など、返された配列で好きなことを行うことができます。それが削除されたものを返すという事実は、ちょっとナンセンスな私見です。メソッドの意図が「要素のセットを切り取る」ことであり、それが唯一の意図である場合は、おそらくそうです。でも、何を切り抜くのかわからないような気がするんですけど、そういう要素を切り捨てる理由はほとんどないですね。既存の配列を変更するのではなく、既存の配列から新しい配列が作成されるconcat、map、reduce、sliceなどのように動作するほうがよいでしょう。それらはすべて連鎖可能であり、それは重要な問題です。配列操作をチェーンすることはかなり一般的です。言語はどちらか一方の方向に進み、可能な限りそれに固執する必要があるようです。Javascriptは機能的で宣言的ではないため、標準からの奇妙な逸脱のように見えます。
今日(2020.04.24)私は、大小のアレイ用に選択したソリューションのテストを実行します。私はChrome 81.0、Safari 13.1、Firefox 75.0のMacOs High Sierra 10.13.6でそれらをテストしました。
すべてのブラウザ
slice
、reduce
(D、E、F)に基づく小さなアレイの非インプレースソリューションでは、通常、インプレースソリューションよりも10倍から100倍高速です。splice
(AI、BI、CI)に基づくインプレースソリューションが最速でした(場合によっては、最大100倍ですが、配列のサイズによって異なります)。テストは、インプレースソリューション(AI、BI、CI)と非インプレースソリューション(D、E、F)の2つのグループに分けられ、2つのケースで実行されました。
テストされたコードは以下のスニペットに示されています
クロムの小さな配列の結果の例は以下のとおりです