Tôi đang tìm kiếm một phương thức chèn mảng JavaScript, theo kiểu:
arr.insert(index, item)
Tốt hơn là trong jQuery, nhưng bất kỳ triển khai JavaScript nào cũng sẽ làm vào thời điểm này.
Tôi đang tìm kiếm một phương thức chèn mảng JavaScript, theo kiểu:
arr.insert(index, item)
Tốt hơn là trong jQuery, nhưng bất kỳ triển khai JavaScript nào cũng sẽ làm vào thời điểm này.
Câu trả lời:
Những gì bạn muốn là splice
chức năng trên đối tượng mảng gốc.
arr.splice(index, 0, item);
sẽ chèn item
vào arr
chỉ mục đã chỉ định ( 0
trước tiên xóa các mục, nghĩa là nó chỉ là một mục chèn).
Trong ví dụ này, chúng ta sẽ tạo một mảng và thêm một phần tử vào nó vào chỉ mục 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)
sẽ loại bỏ 3 phần tử bắt đầu từ chỉ mục 2. Không vượt qua lần thứ 3 .... Các tham số thứ N không có gì được chèn vào. Vì vậy, cái tên insert()
cũng không làm điều đó công lý.
Bạn có thể thực hiện Array.insert
phương pháp bằng cách thực hiện điều này:
Array.prototype.insert = function ( index, item ) {
this.splice( index, 0, item );
};
Sau đó, bạn có thể sử dụng nó như:
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)); }
Khác với splice, bạn có thể sử dụng phương pháp này sẽ không làm thay đổi mảng ban đầu, nhưng sẽ tạo ra một mảng mới với mục được thêm vào. Bạn thường nên tránh đột biến bất cứ khi nào có thể. Tôi đang sử dụng toán tử lây lan ES6 ở đây.
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]
Điều này có thể được sử dụng để thêm nhiều hơn một mục bằng cách điều chỉnh chức năng một chút để sử dụng toán tử còn lại cho các mục mới và cũng lan truyền nó trong kết quả trả về
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
Phương pháp mảng tùy chỉnh/* 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;
};
Nó có thể chèn nhiều phần tử (như bản địa splice
) và hỗ trợ chuỗi:
["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;
};
Nó có thể hợp nhất các mảng từ các đối số với mảng đã cho và cũng hỗ trợ chuỗi:
["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"]
. Tại sao không "d"
bao gồm? Dường như với tôi rằng nếu bạn đặt 6 làm tham số thứ hai slice()
và có 6 phần tử trong mảng bắt đầu từ chỉ mục đã chỉ định, thì bạn sẽ nhận được tất cả 6 phần tử trong giá trị trả về. (Tài liệu nói howMany
về tham số đó.) Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3);
=>[ ]
slice
phương thức và không splice
, mà bạn đang đề cập đến trong bình luận. Tham số thứ hai của slice
(được đặt tên end
) là chỉ số dựa trên zero để kết thúc trích xuất. slice
chiết xuất lên đến nhưng không bao gồmend
. Do đó sau khi insert
bạn có ["a", "b", "X", "Y", "Z", "c", "d"]
, từ đó slice
trích xuất các phần tử có chỉ số từ 1
lên đến 6
, tức là từ "b"
đến "d"
nhưng không bao gồm "d"
. Liệu nó có ý nghĩa?
Nếu bạn muốn chèn nhiều phần tử vào một mảng cùng một lúc, hãy xem câu trả lời Stack Overflow này: Cách tốt hơn để ghép một mảng thành một mảng trong javascript
Ngoài ra đây là một số chức năng để minh họa cả hai ví dụ:
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;
}
Cuối cùng, đây là một jsFiddle để bạn có thể tự mình xem nó: http://jsfiddle.net/luisperezphd/Wc8aS/
Và đây là cách bạn sử dụng các chức năng:
// 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);
Đối với lập trình chức năng phù hợp và mục đích xích, một phát minh Array.prototype.insert()
là rất cần thiết. Thực tế mối nối có thể hoàn hảo nếu nó trả về mảng bị đột biến thay vì một mảng trống hoàn toàn vô nghĩa. Nó đây rồi
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>");
Vâng, ở trên với Array.prototype.splice()
một biến đổi mảng ban đầu và một số có thể phàn nàn như "bạn không nên sửa đổi những gì không thuộc về bạn" và điều đó cũng có thể đúng. Vì vậy, đối với phúc lợi công cộng, tôi muốn cung cấp cho người khác Array.prototype.insert()
mà không làm thay đổi mảng ban đầu. Nó đi từ đây;
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
đổi mảng ban đầu, tôi không nghĩ "lập trình chức năng phù hợp" thuộc về bất cứ nơi nào trong vùng lân cận splice
.
Tôi khuyên bạn nên sử dụng tinh khiết JavaScript trong trường hợp này, cũng không có phương pháp chèn trong JavaScript, nhưng chúng tôi có một phương pháp mà là một built-in Mảng phương pháp mà không được công việc cho bạn, nó được gọi là mối nối ...
Hãy xem những gì mối nối () ...
Phương thức splice () thay đổi nội dung của một mảng bằng cách loại bỏ các phần tử hiện có và / hoặc thêm các phần tử mới.
OK, hãy tưởng tượng chúng ta có mảng này dưới đây:
const arr = [1, 2, 3, 4, 5];
Chúng ta có thể loại bỏ 3
như thế này:
arr.splice(arr.indexOf(3), 1);
Nó sẽ trả về 3, nhưng nếu chúng ta kiểm tra mảng bây giờ, chúng ta có:
[1, 2, 4, 5]
Cho đến nay, rất tốt, nhưng làm thế nào chúng ta có thể thêm một phần tử mới vào mảng bằng cách sử dụng mối nối? Hãy đặt lại 3 trong mảng ...
arr.splice(2, 0, 3);
Hãy xem những gì chúng tôi đã làm ...
Chúng tôi sử dụng splice một lần nữa, nhưng lần này cho đối số thứ hai, chúng tôi vượt qua 0 , có nghĩa là chúng tôi muốn xóa không có mục nào, nhưng đồng thời, chúng tôi thêm đối số thứ ba là 3 sẽ được thêm vào chỉ mục thứ hai ...
Bạn nên lưu ý rằng chúng ta có thể xóa và thêm cùng một lúc, ví dụ như bây giờ chúng ta có thể làm:
arr.splice(2, 2, 3);
Sẽ xóa 2 mục tại chỉ mục 2, sau đó thêm 3 mục vào chỉ mục 2 và kết quả sẽ là:
[1, 2, 3, 5];
Điều này cho thấy mỗi mục trong mối nối hoạt động như thế nào:
mảng.splice (bắt đầu, xóaCount, item1, item2, item3 ...)
Nối phần tử đơn vào một chỉ mục cụ thể
//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';
Nối nhiều phần tử vào một chỉ mục cụ thể
//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';
sẽ nối thêm nếu mảng chỉ có 3 phần tử. Nếu có một yếu tố trong chỉ số 3, điều này sẽ được thay thế. Nếu bạn muốn thêm vào cuối, nó là tốt hơn để sử dụngarrName.push('newName1');
Một giải pháp có thể, với việc sử dụng 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);
Đây là hai cách:
const array = [ 'My', 'name', 'Hamza' ];
array.splice(2, 0, 'is');
console.log("Method 1 : ", array.join(" "));
HOẶC LÀ
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(" "));
Mặc dù điều này đã được trả lời, tôi đang thêm ghi chú này cho một cách tiếp cận khác.
Tôi muốn đặt một số mục đã biết vào một mảng, vào các vị trí cụ thể, vì chúng xuất phát từ một "mảng kết hợp" (tức là một đối tượng) mà theo định nghĩa không được đảm bảo theo thứ tự được sắp xếp. Tôi muốn mảng kết quả là một mảng các đối tượng, nhưng các đối tượng phải theo một thứ tự cụ thể trong mảng vì một mảng đảm bảo thứ tự của chúng. Vì vậy, tôi đã làm điều này.
Đầu tiên là đối tượng nguồn, một chuỗi JSONB được lấy từ PostgreSQL. Tôi muốn có nó được sắp xếp theo thuộc tính "thứ tự" trong mỗi đối tượng con.
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);
Vì số lượng nút trong đối tượng được biết đến, trước tiên tôi tạo một mảng với độ dài được chỉ định:
var obj_length = Object.keys(jsonb_obj).length;
var sorted_array = new Array(obj_length);
Và sau đó lặp lại đối tượng, đặt các đối tượng tạm thời mới được tạo vào các vị trí mong muốn trong mảng mà không thực sự có bất kỳ sự "sắp xếp" nào diễn ra.
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);
Bất cứ ai vẫn gặp vấn đề với cái này và đã thử tất cả các tùy chọn ở trên và không bao giờ có nó. Tôi đang chia sẻ giải pháp của mình, điều này là để xem xét rằng bạn sẽ không nói rõ các thuộc tính của đối tượng của bạn so với mảng.
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;
}
Đây là sự kết hợp của việc lặp lại mảng tham chiếu và so sánh nó với đối tượng bạn muốn kiểm tra, chuyển đổi cả hai thành một chuỗi sau đó lặp lại nếu nó khớp. Sau đó, bạn chỉ có thể đếm. Điều này có thể được cải thiện nhưng đây là nơi tôi giải quyết. Hi vọng điêu nay co ich.
Lấy lợi nhuận của phương pháp giảm như sau:
function insert(arr, val, index) {
return index >= arr.length
? arr.concat(val)
: arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
}
Vì vậy, theo cách này, chúng ta có thể trả về một mảng mới (sẽ là một cách chức năng tuyệt vời - tốt hơn nhiều so với sử dụng đẩy hoặc ghép) với phần tử được chèn tại chỉ mục và nếu chỉ mục lớn hơn độ dài của mảng thì nó sẽ được chèn cuối cùng.
Array#splice()
là cách để đi, trừ khi bạn thực sự muốn tránh làm biến đổi mảng. Đưa ra 2 mảng arr1
và arr2
, đây là cách bạn sẽ chèn nội dung arr2
vào arr1
sau phần tử đầu tiên:
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)
Nếu bạn lo lắng về việc thay đổi mảng (ví dụ: nếu sử dụng Immutable.js), thay vào đó bạn có thể sử dụng slice()
, không bị nhầm lẫn splice()
với a 'p'
.
const arr3 = [...arr1.slice(0, 1), ...arr2, ...arr1.slice(1)];
Tôi đã thử điều này và nó đang hoạt động tốt!
var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);
Chỉ mục là vị trí mà bạn muốn chèn hoặc xóa phần tử. 0 tức là các tham số thứ hai xác định số lượng phần tử từ chỉ mục cần xóa mục là các mục mới mà bạn muốn thực hiện trong mảng. Nó có thể là một hoặc nhiều hơn một.
initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");
Đây là một chức năng làm việc mà tôi sử dụng trong một trong các ứng dụng của mình.
Điều này kiểm tra nếu thoát mục
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("");
};
Và sau đó tôi gọi nó dưới đây.
ifExist("friends", [ ' ( ', ' )' ], 1)} // output: ( friends )
ifExist("friends", [ ' - '], 1)} // output: - friends
ifExist("friends", [ ':'], 0)} // output: friends:
Một chút của một chủ đề cũ hơn, nhưng tôi phải đồng ý với Redu ở trên vì splice chắc chắn có một chút giao diện khó hiểu. Và phản hồi được đưa ra bởi cdbajorin rằng "nó chỉ trả về một mảng trống khi tham số thứ hai bằng 0. Nếu nó lớn hơn 0, nó trả về các mục bị xóa khỏi mảng", trong khi chính xác, chứng minh điểm. Mục đích của chức năng là ghép nối hoặc như đã nói trước đó của Jakob Keller, "để tham gia hoặc kết nối, cũng để thay đổi. Bạn có một mảng đã được thiết lập mà hiện tại bạn đang thay đổi có liên quan đến việc thêm hoặc xóa các phần tử ...." giá trị trả về của các phần tử, nếu có, đã bị loại bỏ là khó xử nhất. Và tôi 100% đồng ý rằng phương pháp này có thể phù hợp hơn với chuỗi nếu nó trả về những gì có vẻ tự nhiên, một mảng mới với các phần tử được nối thêm vào. Sau đó, bạn có thể thực hiện những việc như ["19", "17"]. Splice (1,0, "18"). Tham gia ("...") hoặc bất cứ điều gì bạn thích với mảng được trả về. Thực tế là nó trả về những gì đã bị xóa chỉ là IMHO vô nghĩa. Nếu ý định của phương pháp là "cắt ra một tập hợp các yếu tố" và đó chỉ là ý định. Có vẻ như nếu tôi không biết những gì tôi đã cắt bỏ mặc dù, tôi có thể có ít lý do để cắt bỏ những yếu tố đó, phải không? Sẽ tốt hơn nếu nó hoạt động như concat, map, rút gọn, lát, v.v ... trong đó một mảng mới được tạo từ mảng hiện có thay vì làm biến đổi mảng hiện có. Đó là tất cả các chuỗi, và đó là một vấn đề quan trọng. Nó khá phổ biến đối với thao tác mảng chuỗi. Có vẻ như ngôn ngữ cần phải đi theo hướng này hay hướng khác và cố gắng bám sát nó càng nhiều càng tốt. Javascript là chức năng và ít khai báo, nó chỉ có vẻ như là một sai lệch kỳ lạ so với tiêu chuẩn.
Hôm nay (2020.04.24) Tôi thực hiện các thử nghiệm cho các giải pháp được chọn cho các mảng lớn và nhỏ. Tôi đã thử nghiệm chúng trên MacOs High Sierra 10.13.6 trên Chrome 81.0, Safari 13.1, Firefox 75.0.
Đối với tất cả các trình duyệt
slice
và reduce
(D, E, F) thường nhanh hơn gấp 10 lần so với giải pháp tại chỗsplice
(AI, BI, CI) là nhanh nhất (đôi khi ~ 100x - nhưng nó phụ thuộc vào kích thước mảng)Các thử nghiệm được chia thành hai nhóm: giải pháp tại chỗ (AI, BI, CI) và giải pháp không tại chỗ (D, E, F) và được thực hiện cho hai trường hợp
Mã thử nghiệm được trình bày trong đoạn trích dưới đây
Kết quả ví dụ cho mảng nhỏ trên chrome nằm bên dưới