জাভাস্ক্রিপ্ট - অন্য অ্যারের ভিতরে একটি অ্যারে sertোকান


91

অন্য অ্যারের ভিতরে অ্যারে toোকানোর আরও কার্যকর উপায় কী।

a1 = [1,2,3,4,5];
a2 = [21,22];

newArray - a1.insertAt(2,a2) -> [1,2, 21,22, 3,4,5];

স্প্লাইস ব্যবহার করে এ 2 আইট্রেটেড করা যদি এ 2 অ্যারে বড় হয় তবে পারফরম্যান্সের দিক থেকে কিছুটা অবাস্তব লাগে।

ধন্যবাদ


4
একটি সময়ে কটাক্ষপাত আছে stackoverflow.com/questions/586182/...
Endophage

4
এটি একটি আইটেম নয় বরং একটি অ্যারে, সুতরাং স্প্লাইস কাজ করছে না
ic3

উত্তর:


182

আপনি spliceকিছু applyকৌশল সঙ্গে মিলিত ব্যবহার করতে পারেন :

a1 = [1,2,3,4,5];
a2 = [21,22];

a1.splice.apply(a1, [2, 0].concat(a2));

console.log(a1); // [1, 2, 21, 22, 3, 4, 5];

ES2015 + তে, আপনি এটিকে কিছুটা ভাল করার পরিবর্তে স্প্রেড অপারেটরটি ব্যবহার করতে পারেন

a1.splice(2, 0, ...a2);

10
@ আইকিউব: আমি এই পদ্ধতির সাথে প্যাট্রিকের উত্তরের সাথে তুলনা করে কেবল একটি বেঞ্চমার্ক চালিয়েছি। এটি উদাহরণ হিসাবে যেমন a1 এবং a2 দিয়ে শুরু হয় এবং a2 ভেরিয়েবলটিকে 10,000 বারে ইনজেক্ট করে (যাতে শেষ পর্যন্ত আপনার 20,005 উপাদান রয়েছে)। এই পদ্ধতিটি নিয়েছিল: 81 মিমি , স্লাইস + কনক্যাট পদ্ধতিটি 156 মিমি নিয়েছে (ক্রোম 13 এ পরীক্ষিত) । অবশ্যই, এটি স্ট্যান্ডার্ড সতর্কতার সাথে আসে যে বেশিরভাগ ক্ষেত্রে, সুগতি গতির চেয়ে আরও গুরুত্বপূর্ণ হবে।
নিকফ

4
@ নিক: ক্রোমে যদি অ্যারেগুলি 130000 আইটেম ধরে রাখে তবে স্ট্যাকওভারফ্লো applyব্যতিক্রম ছুঁড়ে ফেলবে। jsfiddle.net/DcHCY এছাড়াও jsPerf ঘটবে আমি মুক্তিযোদ্ধা এবং আইই বিশ্বাস থ্রেশহোল্ড প্রায় 500K হয়
নাঃ

আপনি স্প্লাইস সরাসরি কল করার এবং যুক্তিগুলি পাস করার বিপরীতে কেন আবেদন প্রয়োগ করবেন?
পিটার পি।

@ ফ্রানয়েইসওয়াহাল, এটি একটি গুরুতর বিষয় যা লোকেরা প্রায়শই তাদের উত্তরে উপেক্ষা করে। আমি আপনার উদাহরণটি নিয়েছি এবং এটি 1 এম উপাদানগুলির উত্তরে কাজ করেছি: stackoverflow.com/a/41466395/1038326
গ্যাব্রিয়েল কোহেন

আমি সবেমাত্র এটি (জুন ২০১)) চেষ্টা করেছি এবং ছোট অ্যারের আকার এবং বৃহত অ্যারে উভয় আকারের (ক্রোম, এফএফ এবং এজ তে) দ্রুততম উপায় target.slice(0, insertIndex).concat(insertArr, target.slice(insertIndex)); jsperf.com/inserting-an-array-within-an-array
অ্যালেক্স দিমা


14

প্রথমে ভুল ছিল concat()পরিবর্তে ব্যবহার করা উচিত ছিল।

var a1 = [1,2,3,4,5],
    a2 = [21,22],
    startIndex = 0,
    insertionIndex = 2,
    result;    

result = a1.slice(startIndex, insertionIndex).concat(a2).concat(a1.slice(insertionIndex));

উদাহরণ: http://jsfiddle.net/f3cae/1/

এই অভিব্যক্তিটি প্রথম দুটি উপাদান (যেখানে সূচনা সূচক, এবং পরিবর্তিত না হলেও উপাদান মুছুনি হিসাব ) ফেরত দিতে slice(0, 2)[ডক্স] ব্যবহার করে ।a102a1

মধ্যবর্তী ফলাফল :[1,2]

এরপরে এটি concat(a2)[ডক্স]a2 এর শেষে যুক্ত করতে ব্যবহার করে [1,2]

অন্তর্বর্তী ফলাফলের : [1,2,21,22]

এরপরে, এই অভিব্যক্তিটির লেজ a1.slice(2)প্রান্তের পিছনে বলা হয় .concat(), যার পরিমাণ [1,2,21,22].concat(a1.slice(2))

একটি কল slice(2), একটি ইতিবাচক পূর্ণসংখ্যার যুক্তি সহ, ২ য় মৌলের পরে সমস্ত উপাদানকে প্রাকৃতিক সংখ্যা দ্বারা গণনা করা হবে (যেমন রয়েছে, পাঁচটি উপাদান রয়েছে, তাই [3,4,5]ফিরে আসবে a1)। এটি বলার আরেকটি উপায় হ'ল একক একক পূর্ণসংখ্যার সূচক যুক্তিটি a1.slice()অ্যারেতে কোন অবস্থান থেকে এলিমেন্টগুলি ফেরত দেওয়া শুরু করবে (সূচক 2 তৃতীয় উপাদান)।

মধ্যবর্তী ফলাফল :[1,2,21,22].concat([3,4,5])

অবশেষে, দ্বিতীয় .concat()যোগ [3,4,5]শেষে [1,2,21,22]

ফলাফল :[1,2,21,22,3,4,5]

এটি পরিবর্তনের জন্য লোভনীয় হতে পারে Array.prototype, তবে প্রোটোটাইপাল উত্তরাধিকার ব্যবহার করে অ্যারে অবজেক্টটি প্রসারিত করে আপনার প্রকল্পগুলিতে নতুন অবজেক্টটি ইনজেকশন করতে পারে।

তবে, প্রান্তে যারা থাকেন তাদের জন্য ...

উদাহরণ: http://jsfiddle.net/f3cae/2/

Array.prototype.injectArray = function( idx, arr ) {
    return this.slice( 0, idx ).concat( arr ).concat( this.slice( idx ) );
};

var a1 = [1,2,3,4,5];
var a2 = [21,22];

var result = a1.injectArray( 2, a2 );

আমি - নয় - [-> [1,2, [21,22], 3,4,5] সাথে
আই

কাজ! অনেক অনেক ধন্যবাদ, আসুন কিছু দিন অপেক্ষা করুন তবে এটি সেরা উত্তর হিসাবে ... অদ্ভুত তাদের এইগুলির জন্য জেএস ফাংশন নেই।
আইটি 3

আমি এটি আরও ভাল পছন্দ করি
কিমচি ম্যান

সংক্ষেপে, জেএস ইঞ্জিনটি অবশ্যই এক্সপ্রেশন শেষ হওয়ার আগে চারটি অ্যারে ফিরিয়ে আনবে। আমি সমাধানটির যুক্তি পছন্দ করি তবে স্থান বিবেচনার ক্ষেত্রে এটি সর্বোত্তম নাও হতে পারে। তবে আমি সম্মত হই যে এটি নিফটি এবং খুব ক্রস ব্রাউজারের সাথে সামঞ্জস্যপূর্ণ। সংগ্রহগুলিতে কাজ করার কারণে স্প্রেড অপারেটরটি ব্যবহার করতে ব্যয় করতে হবে, তবে আমি দীর্ঘমেয়াদে চারটি অ্যারে ফিরিয়ে নিতে পারব।
অ্যান্টনি রুটলেজ

4

বিস্তার অপারেটর একটি অভিব্যক্তি জায়গায় যেখানে একাধিক আর্গুমেন্ট বা একাধিক উপাদানের (অ্যারে লিটারেল জন্য) (ফাংশন কলের জন্য) আশা করা যায় এর মধ্যে প্রসারিত করা অনুমতি দেয়।

a2 = [21,22];
a1 = [1,2,...a2,3,4,5];//...a2 is use of spread operator
console.log(a1);


3

আমি এটি করার একটি উপায় splice()এবং পুনরাবৃত্তির কোনও উপায় খুঁজতে চেয়েছি : http://jsfiddle.net/jfriend00/W9n27/

a1 = [1,2,3,4,5];
a2 = [21,22];

a2.unshift(2, 0);          // put first two params to splice onto front of array
a1.splice.apply(a1, a2);   // pass array as arguments parameter to splice
console.log(a1);           // [1, 2, 21, 22, 3, 4, 5];

সাধারণ উদ্দেশ্যে ফাংশন ফর্ম:

function arrayInsertAt(destArray, pos, arrayToInsert) {
    var args = [];
    args.push(pos);                           // where to insert
    args.push(0);                             // nothing to remove
    args = args.concat(arrayToInsert);        // add on array to insert
    destArray.splice.apply(destArray, args);  // splice it in
}

এটি a2পাশাপাশি অ্যারে পরিবর্তন করে , যা সম্ভবত বেশ অযাচিত। এছাড়াও, আপনি যেতে প্রয়োজন হবে না Array.prototypeযখন আপনি ডানে সেখানে ফালি কার্যকারিতা থাকতে a1বা a2
নিকফ

আমি সচেতন ছিলাম এটি এ 2 সংশোধন করছে। ওপি সিদ্ধান্ত নিতে পারে এটি সমস্যা কিনা। পদ্ধতিটি পেতে প্রোটোটাইপে গিয়ে কোনও সমস্যা আছে কি? এটি আমার কাছে আরও উপযুক্ত বলে মনে হয়েছিল যেহেতু আমি কেবল পদ্ধতিটি চেয়েছিলাম এবং পদ্ধতিতে বস্তুটি যুক্ত করা হচ্ছে apply()
jender00

ঠিক আছে না, এটি ঠিক একই কাজ, তবে Array.prototype.splicea1.splice
একটিটি

সাধারণ উদ্দেশ্যে অ্যারে সন্নিবেশ ফাংশন যুক্ত করা হয়েছে।
jender00

.concatএকটি নতুন অ্যারে প্রদান করে, এটি বিদ্যমানটির মতো পরিবর্তন করে না splice। হওয়া উচিতargs = args.concat(arrayToInsert);
নিকফ

3

এই প্রশ্নের এখানে কিছু সত্যই সৃজনশীল উত্তর রয়েছে। এখানে অ্যারে দিয়ে শুরু করা তাদের জন্য একটি সহজ সমাধান। এটি যদি ইচ্ছা হয় তবে ECMAScript 3 কমপ্লায়েন্ট ব্রাউজারে সমস্ত ভাবেই কাজ করা যায়।

শুরু করার আগে স্প্লাইস সম্পর্কে কিছু জানুন।

মজিলা বিকাশকারী নেটওয়ার্ক: অ্যারে.প্রোটোটাইপ.স্প্লাইস ()

প্রথমে এর দুটি গুরুত্বপূর্ণ ফর্ম বুঝুন .splice()

let a1 = [1,2,3,4],
    a2 = [1,2];

পদ্ধতি 1) একটি পছন্দসই সূচক থেকে শুরু করে এক্স (মুছে ফেলা) উপাদানগুলি সরান।

let startIndex = 0, 
    deleteCount = 2;

a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]

পদ্ধতি 2) অ্যারের শেষে পছন্দসই সূচনা সূচকের পরে উপাদানগুলি সরান।

a1.splice(2); // returns [3,4], a1 would be [1,2]

ব্যবহার করে .splice(), একটি লক্ষ্য হতে পারে a1উপরের দুটি ফর্মের একটি ব্যবহার করে মাথা এবং লেজ অ্যারেগুলিতে বিভক্ত হওয়া।

পদ্ধতি # 1 ব্যবহার করে, ফেরতের মানটি মাথা এবং a1লেজ হয়ে যাবে ।

let head = a1.splice(startIndex, deleteCount); // returns [1,2], a1 would be [3,4]

এখন, একের মধ্যে ঝাপটায় পড়ে মাথা, শরীর ( a2) এবং লেজ কাটা করুন

[].concat(head, a2, a1);

সুতরাং, এই সমাধানটি এখনও পর্যন্ত উপস্থাপিত অন্য যে কোনও তুলনায় বাস্তব বিশ্বের মতো। আপনি কি লেগোসের সাথে এটি করবেন? ;-) এখানে একটি ফাংশন, পদ্ধতি # 2 ব্যবহার করে সম্পন্ন করা হয়েছে।

/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*/
function insertArray(target, body, startIndex)
{
    let tail = target.splice(startIndex); // target is now [1,2] and the head
    return [].concat(target, body, tail);
}

let newArray = insertArray([1, 2, 3, 4], ["a", "b"], 2); // [1, 2, "a", "b", 3, 4]

সংক্ষিপ্ত:

/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*/
function insertArray(target, body, startIndex)
{
    return [].concat(target, body, target.splice(startIndex));
}

নিরাপদ:

/**
*@param target Array The array to be split up into a head and tail.
*@param body Array The array to be inserted between the head and tail.
*@param startIndex Integer Where to split the target array.
*@throws Error The value for startIndex must fall between the first and last index, exclusive.
*/
function insertArray(target, body, startIndex)
{
    const ARRAY_START = 0,
          ARRAY_END = target.length - 1,
          ARRAY_NEG_END = -1,
          START_INDEX_MAGNITUDE = Math.abs(startIndex);

    if (startIndex === ARRAY_START) {
        throw new Error("The value for startIndex cannot be zero (0).");
    }

    if (startIndex === ARRAY_END || startIndex === ARRAY_NEG_END) {
        throw new Error("The startIndex cannot be equal to the last index in target, or -1.");
    }

    if (START_INDEX_MAGNITUDE >= ARRAY_END) {
        throw new Error("The absolute value of startIndex must be less than the last index.");
    }

    return [].concat(target, body, target.splice(startIndex));
}

এই সমাধানের সুবিধার মধ্যে রয়েছে:

1) সমাধানের উপর একটি সাধারণ ভিত্তি প্রাধান্য দেয় - একটি খালি অ্যারে পূরণ করুন।

2) মাথা, শরীর এবং লেজের নামকরণ প্রাকৃতিক অনুভূত হয়।

3) ডাবল কল নেই .slice()। মোটেও কাটছে না।

4) না .apply()। অত্যন্ত অপ্রয়োজনীয়।

5) পদ্ধতি শৃঙ্খলা এড়ানো হয়।

6) ECMAScript 3 এবং 5 এ কেবল বা varপরিবর্তে ব্যবহার করে কাজ করে ।letconst

**)) এটি নিশ্চিত করে যে শরীরে থাপ্পড় দেওয়ার জন্য একটি মাথা এবং লেজ থাকবে, অন্য অনেকগুলি সমাধান উপস্থাপনের বিপরীতে। আপনি যদি আগে বা পরে সীমা যুক্ত করেন তবে আপনার অন্তত ব্যবহার করা উচিত .concat()!!!!

দ্রষ্টব্য: স্প্রেড ওপেনেটর ব্যবহার ...এই সমস্ত কিছু সম্পাদন করা সহজ করে তোলে।


0
var a1 = [1,2,3,4,5];
var a2 = [21,22];

function injectAt(d, a1, a2) {
    for(var i=a1.length-1; i>=d; i--) {
        a1[i + a2.length] = a1[i];
    }
    for(var i=0; i<a2.length; i++) {
        a1[i+d] = a2[i];
    }
}

injectAt(2, a1, a2);

alert(a1);

0

এখানে কোনও বিশেষ কৌশল ছাড়া আমার সংস্করণটি রয়েছে:

function insert_array(original_array, new_values, insert_index) {
    for (var i=0; i<new_values.length; i++) {
        original_array.splice((insert_index + i), 0, new_values[i]);
    }
    return original_array;
}

এই ক্ষেত্রে, প্রতিটি পুনরাবৃত্তির জন্য insert_index বাড়ানোর পরিবর্তে, কেবলমাত্র নতুন_মূল্য অ্যারের বিপরীতে () নতুন করা সহজ হতে পারে। অবশ্যই, যখন start_index শূন্য বা start_index - 1 হয়, তখন এই সমাধানটির কার্যকারিতা দুর্বল হয়, কেবল কোনও স্পষ্ট লুপ ছাড়াই .ccat () ব্যবহার করার সাথে তুলনা করুন বা (আনশিফ্ট) (বা পুশ ()) এর সাথে তুলনা করুন .apply()
অ্যান্টনি রটলেজ

0

আপনি যদি নতুনটি তৈরি না করেই অ্যারেতে অন্য অ্যারে সন্নিবেশ করতে চান তবে সবচেয়ে সহজ উপায় হয় হয় pushবা এর unshiftসাথে ব্যবহার করাapply

যেমন:

a1 = [1,2,3,4,5];
a2 = [21,22];

// Insert a1 at beginning of a2
a2.unshift.apply(a2,a1);
// Insert a1 at end of a2
a2.push.apply(a2,a1);

এটি উভয় কারণেই কাজ করে pushএবং unshiftএকটি পরিবর্তনশীল সংখ্যক আর্গুমেন্ট গ্রহণ করে। একটি বোনাস, আপনি সহজেই কোন প্রান্ত থেকে অ্যারে সংযুক্ত করতে পারেন তা চয়ন করতে পারেন!


আপনার পরামর্শ অনুসারে কেবল কিছু করার মাধ্যমে a1.concat(a2)বা a2.concat(a1)আমি আরও সহজ কিছু তৈরি করেছি। তবে ইস্যুটি অ্যারে বাউন্ডের মধ্যে একটি অ্যারে সন্নিবেশ করছে, শুরু বা শেষের দিকে একচেটিয়াভাবে অ্যারে যোগ করছে না। ;-)
অ্যান্থনি রুটলেজ

0

অন্য থ্রেডে উল্লিখিত হিসাবে, উপরের উত্তরগুলি খুব বড় অ্যারে (200 কে উপাদান )গুলিতে কাজ করবে না। স্প্লাইস এবং ম্যানুয়াল পুশ জড়িত বিকল্প উত্তর দেখুন: https://stackoverflow.com/a/41465578/1038326

Array.prototype.spliceArray = function(index, insertedArray) {
    var postArray = this.splice(index);
    inPlacePush(this, insertedArray);
    inPlacePush(this, postArray);

    function inPlacePush(targetArray, pushedArray) {
  // Not using forEach for browser compatability
        var pushedArrayLength = pushedArray.length;
        for (var index = 0; index < pushedArrayLength; index++) {
           targetArray.push(pushedArray[index]);
       }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.