জাভাস্ক্রিপ্ট / jQuery এ অ্যারে থেকে একাধিক উপাদান সরান


117

আমার দুটি অ্যারে আছে প্রথম অ্যারেটিতে কিছু মান রয়েছে যখন দ্বিতীয় অ্যারেটিতে মানগুলির সূচক রয়েছে যা প্রথম অ্যারে থেকে সরানো উচিত। উদাহরণ স্বরূপ:

var valuesArr = new Array("v1","v2","v3","v4","v5");   
var removeValFromIndex = new Array(0,2,4);

আমি সূচকের এ মান উপস্থিত সরাতে চান 0,2,4থেকে valuesArr। আমি ভেবেছিলাম যে স্থানীয় spliceপদ্ধতিটি সাহায্য করতে পারে তাই আমি এলাম:

$.each(removeValFromIndex,function(index,value){
    valuesArr.splice(value,1);
});

তবে এটি কার্যকর হয়নি কারণ প্রত্যেকের পরে splice, মানগুলির সূচকগুলি valuesArrআলাদা ছিল। আমি এই সমস্যাটি অস্থায়ী অ্যারে ব্যবহার করে এবং দ্বিতীয় মানগুলিতে সমস্ত মান অনুলিপি করে সমাধান করতে পারতাম, তবে আমি ভাবছিলাম যে এমন কোনও নেটিভ পদ্ধতি আছে যেখানে আমরা একাধিক সূচকগুলি পাস করতে পারি যেখানে অ্যারে থেকে মানগুলি সরিয়ে নেওয়া যায়।

আমি একটি jQuery সমাধান পছন্দ করব। (আমি grepএখানে ব্যবহার করতে পারি কিনা তা নিশ্চিত নয় )

উত্তর:


255

প্লেইন পুরানো forলুপটি সর্বদা থাকে :

var valuesArr = ["v1","v2","v3","v4","v5"],
    removeValFromIndex = [0,2,4];    

for (var i = removeValFromIndex.length -1; i >= 0; i--)
   valuesArr.splice(removeValFromIndex[i],1);

দিয়ে যান removeValFromIndexবিপরীত ক্রম এবং আপনি যা করতে পারেন.splice() এখনো টু করা সরানো হয়নি আইটেম ইনডেক্স আপ তালগোল পাকানো ছাড়া।

উপরের নোটটিতে আমি দুটি অ্যারে ঘোষণার জন্য বর্গাকার বন্ধনীর সাথে অ্যারে-লিটারাল সিনট্যাক্স ব্যবহার করেছি। এটি প্রস্তাবিত বাক্য গঠন যা কারণ new Array()আপনি কয়টি প্যারামিটারে প্রবেশ করেছেন তার উপর নির্ভর করে এটি ভিন্নভাবে প্রতিক্রিয়া জানায় use

সম্পাদনা : সূচকের অ্যারে সম্পর্কে অন্য একটি উত্তর সম্পর্কে আপনার মন্তব্যটি দেখেছি অগত্যা কোনও নির্দিষ্ট ক্রমে নয়। যদি এটি কেসটি হয় তবে এটি শুরু করার আগে কেবল উতর ক্রমে সাজান:

removeValFromIndex.sort(function(a,b){ return b - a; });

এবং $.each()আপনার পছন্দ মতো লুপিং / / ইত্যাদি পদ্ধতি অনুসরণ করুন ।



5
@ মুহাম্মাদ উমার - না, আপনি যদি এটি সঠিকভাবে করেন তবে তা নয়, যা আমার উত্তর ব্যাখ্যা করে।
nnnnnn

5
বিপরীত অর্ডার সচেতনতার জন্য ধন্যবাদ।
ড্যানিয়েল নলবাচ

2
+1, আমি বুঝতে পারি না যে বিচ্ছিন্নভাবে আমাকে স্প্লাইসটি করতে হবে, যদিও প্রতিটি ফর ব্যবহারের পরিবর্তে আমার পদ্ধতির ব্যবহার হচ্ছে$.each(rvm.reverse(), function(e, i ) {})
লুইস স্ট্যানলি জোভেল

1
এটি কেবল তখনই কাজ করবে যদি removeValFromIndex আরোহী ক্রম অনুসারে বাছাই করা হয়
কুণাল বুড়ঙ্গি 21'১৯ ই

24

লোড্যাশ / আন্ডারস্কোরের সাথে না যাওয়ার সময় আমি এটি ব্যবহার করি:

while(IndexesToBeRemoved.length) {
    elements.splice(IndexesToBeRemoved.pop(), 1);
}

মার্জিত সমাধান! প্রথমে আমি ভেবেছিলাম এটি কার্যকর হবে না কারণ আমি ভেবেছিলাম যে যতবার আপনি কল sliceকরবেন তখনই আপনাকে সূচিগুলি অপসারণ করতে হবে (-১ অন IndexestoBeRemoved), তবে এটি বাস্তবে কার্যকর হয়!
রেনাটো গামা

2
খুব চালাক
ফারজাদ ওয়াইজেড

11
কেবলমাত্র IndexesToBeRemovedঅ্যারেটিকে আরোহণের দ্বারা বাছাই করা হলে এই সমাধানটি কাজ করা হয়।
xfg

সেই সূচকগুলি প্রথম স্প্লাইসের পরে অবৈধ হবে।
shinzou

@ শিনজৌ - IndexesToBeRemovedসাজানো থাকলে নয় (আরোহণ)।
nnnnnn

18

না in-placeকিন্তু ব্যবহার করে grepএবং এর inArrayফাংশন করা যেতে পারে jQuery

var arr = $.grep(valuesArr, function(n, i) {
    return $.inArray(i, removeValFromIndex) ==-1;
});

alert(arr);//arr contains V2, V4

এই কোলাহলটি পরীক্ষা করে দেখুন


যদি আপনি কেবল বলেছিলেন তবে এটি স্থানের (যথেষ্ট valuesArr = $.grep(...);
পরিমাণের

1
@nnnnn হা হা হা আমি একটি সভার জন্য যাচ্ছিলাম (আপনি জানেন তারা আপনাকে এত উত্পাদনশীল করে তোলে) তাই খুব বেশি পরীক্ষা-নিরীক্ষা করেননি।
TheVilageIdiot

1
@ cept0 ডাউনটা কেন? ওপি একটি jQuery সমাধান চেয়েছিল asked
Ste77

তোমাকে অনেক ধন্যবাদ! @
দ্য

jsfiddler - 404 ত্রুটি We আমরা সত্যিকারের জন্য দুঃখিত, কিন্তু এরকম কোনও পৃষ্ঠা নেই।
অ্যাশ

17

আমি আপনাকে অ্যারে.প্রোটোটাইপ.ফিল্টার ব্যবহার করার পরামর্শ দিচ্ছি

var valuesArr = ["v1","v2","v3","v4","v5"];
var removeValFrom = [0, 2, 4];
valuesArr = valuesArr.filter(function(value, index) {
     return removeValFrom.indexOf(index) == -1;
})

ফিল্টারটির ভিতরে সূচি ... সর্বোত্তম নয়
আলভারো


গ্রেট! এখন আমি ঘুমাতে পারি :)
ফিরমান্যাসি

7
function filtermethod(element, index, array) {  
    return removeValFromIndex.find(index)
}  
var result = valuesArr.filter(filtermethod);

MDN রেফারেন্স এখানে


@ ishষিপ 899 ফ্রিডলটি নিচে রয়েছে
mate64

@ কর্ণা: ফিজল নিচে রয়েছে
rষিপি 89

1
দয়া করে মনে রাখবেন যে লেখার সময় (জুন ২০১৪), অ্যারে.প্রোটোটাইপ.ফাইন্ড বর্তমান ইএস 6 খসড়ার অংশ এবং কেবলমাত্র বর্তমান ফায়ারফক্সে
ওলি কে

6

খাঁটি জেএসে আপনি অ্যারেটি পিছনের দিকে লুপ করতে পারেন, সুতরাং splice()লুপের পরবর্তী উপাদানগুলির সূচকগুলি বিশৃঙ্খলা করবে না:

for (var i = arr.length - 1; i >= 0; i--) {
    if ( yuck(arr[i]) ) {
        arr.splice(i, 1);
    }
}

ইয়াক কাজ করে না কোনও ফাংশন নয়, সুতরাং ধরে নেওয়া হ'ল এটি অযাচিত উপাদান সূচকগুলির সূচক, এবং ব্যবহৃত ইয়াক [
আরআর

5

O(n)সময় সহ উত্তর পোস্ট করা প্রয়োজন বলে মনে হয় :)। স্প্লাইস সমাধানের সাথে সমস্যাটি হ'ল অ্যারেটির অন্তর্নিহিত বাস্তবায়নের কারণে আক্ষরিক অর্থে অ্যারে হওয়ায় প্রতিটি spliceকলটিতে O(n)সময় লাগবে । এই আচরণটি কাজে লাগানোর জন্য যখন আমরা উদাহরণ স্থাপন করি তখন এটি সর্বাধিক উচ্চারিত হয়:

var n = 100
var xs = []
for(var i=0; i<n;i++)
  xs.push(i)
var is = []
for(var i=n/2-1; i>=0;i--)
  is.push(i)

এটি মধ্য থেকে শুরু পর্যন্ত শুরু হওয়া উপাদানগুলি সরিয়ে দেয়, সুতরাং প্রতিটি অপসারণ জেএস ইঞ্জিনকে n/2উপাদানগুলি অনুলিপি করতে বাধ্য করে, আমাদের কাছে(n/2)^2 মোট কপি অপারেশন রয়েছে যা চতুর্ভুজীয় is

স্প্লাইস সলিউশন (ধরে নেওয়া isহচ্ছে যে ওভারহেডগুলি থেকে মুক্তি পেতে ইতিমধ্যে হ্রাসমান ক্রমে সাজানো হয়েছে) এরকম হয়:

for(var i=0; i<is.length; i++)
  xs.splice(is[i], 1)

যাইহোক, লিনিয়ার টাইম সলিউশনটি কার্যকর করা কঠিন নয়, স্ক্র্যাচ থেকে অ্যারেটি পুনর্নির্মাণ করে একটি মাস্ক ব্যবহার করে দেখুন যে আমরা উপাদানগুলি অনুলিপি করছি কিনা (সাজানোর মাধ্যমে এটি এতে চাপ দেবে O(n)log(n))। নিম্নলিখিতটি এরূপ বাস্তবায়ন ( maskগতির জন্য এটি বুলিয়ান উল্টানো নয় ):

var mask = new Array(xs.length)
for(var i=is.length - 1; i>=0; i--)
  mask[is[i]] = true
var offset = 0
for(var i=0; i<xs.length; i++){
  if(mask[i] === undefined){
    xs[offset] = xs[i]
    offset++
  }
}
xs.length = offset

আমি এটি jsperf.comচালিয়েছি এমনকি n=100স্প্লাইস পদ্ধতিটিও পুরো 90% ধীর। বৃহত্তর জন্য nএই পার্থক্য অনেক বেশি হবে।


5

দ্রুত ES6 একটি লাইনার:

const valuesArr = new Array("v1","v2","v3","v4","v5");   
const removeValFromIndex = new Array(0,2,4);

const arrayWithValuesRemoved = valuesArr.filter((value, i) => removeValFromIndex.includes(i))

আপনার কোডটি দ্রুত চালানো উচিত যদি আপনি এর পরিবর্তে removeValFromIndexএকটি Set()ব্যবহার করেন এবং ব্যবহার করেন । removeValFromIndex.hasincludes
বোরিস

5

একটি সহজ এবং দক্ষ (রৈখিক জটিলতা) ফিল্টার এবং সেট ব্যবহার করে সমাধান :

const valuesArr = ['v1', 'v2', 'v3', 'v4', 'v5'];   
const removeValFromIndex = [0, 2, 4];

const indexSet = new Set(removeValFromIndex);

const arrayWithValuesRemoved = valuesArr.filter((value, i) => !indexSet.has(i));

console.log(arrayWithValuesRemoved);

এই প্রয়োগের দুর্দান্ত সুবিধাটি হ'ল সেট লুকআপ অপারেশন ( hasফাংশন) একটি ধ্রুবক সময় নেয়, উদাহরণস্বরূপ নেভাসের উত্তরের চেয়ে দ্রুত।


@ মিশেলপ্যাকোসিওন খুশিতে সাহায্য করেছেন :)
আলবার্তো ত্রিন্ডে ট্যাভারেস

3

এটি আমার পক্ষে ভাল কাজ করে এবং যখন বস্তুর একটি অ্যারে থেকেও মুছে ফেলা যায়:

var array = [ 
    { id: 1, name: 'bob', faveColor: 'blue' }, 
    { id: 2, name: 'jane', faveColor: 'red' }, 
    { id: 3, name: 'sam', faveColor: 'blue' }
];

// remove people that like blue

array.filter(x => x.faveColor === 'blue').forEach(x => array.splice(array.indexOf(x), 1));

এটি লেখার জন্য আরও ছোট একটি কার্যকর উপায় থাকতে পারে তবে এটি কাজ করে।


2

ES5 ব্যবহার করে একটি সহজ সমাধান। আজকাল বেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য এটি আরও উপযুক্ত বলে মনে হয়, যেহেতু অনেকেই আর jQuery ইত্যাদির উপর নির্ভর করতে চান না etc.

সরানো সূচিগুলি যখন আরোহী ক্রমে সাজানো হয়:

var valuesArr = ["v1", "v2", "v3", "v4", "v5"];   
var removeValFromIndex = [0, 2, 4]; // ascending

removeValFromIndex.reverse().forEach(function(index) {
  valuesArr.splice(index, 1);
});

সরানো সূচিগুলি যখন সাজানো হয় না:

var valuesArr = ["v1", "v2", "v3", "v4", "v5"];   
var removeValFromIndex = [2, 4, 0];  // unsorted

removeValFromIndex.sort(function(a, b) { return b - a; }).forEach(function(index) {
  valuesArr.splice(index, 1);
});

1

আপনি প্রতিস্থাপন করে আপনার কোড সংশোধন করতে পারেন removeValFromIndexসঙ্গে removeValFromIndex.reverse()। যদি সেই অ্যারেটি আরোহী ক্রম ব্যবহারের গ্যারান্টিযুক্ত না হয় তবে আপনি পরিবর্তে এটি ব্যবহার করতে পারেন removeValFromIndex.sort(function(a, b) { return b - a })


আমার কাছে দেখতে দুর্দান্ত লাগছে - jsfiddle.net/mrtsherman/gDcFu/2 । যদিও এটি অনুমান করে যে অপসারণের তালিকাটি ক্রমে রয়েছে।
mrtsherman

@ মিনোপ্রেট: ধন্যবাদ তবে এটি কেবল তখনই কাজ করবে যদি ইনডেক্সগুলি removeValFromIndexক্রমবর্ধমান ক্রমে থাকে।
xyz


1

আপনি যদি আন্ডারস্কোর.জে ব্যবহার করছেন তবে আপনি _.filter()আপনার সমস্যার সমাধান করতে পারেন ।

var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
var filteredArr = _.filter(valuesArr, function(item, index){
                  return !_.contains(removeValFromIndex, index);
                });

অতিরিক্ত হিসাবে, আপনি যদি সূচকের পরিবর্তে আইটেমের একটি তালিকা ব্যবহার করে আইটেমগুলি সরিয়ে দেওয়ার চেষ্টা করছেন তবে আপনি সহজভাবে ব্যবহার করতে _.without()পারেন:

var valuesArr = new Array("v1","v2","v3","v4","v5");
var filteredArr = _.without(valuesArr, "V1", "V3");

এখন filteredArrহওয়া উচিত["V2", "V4", "V5"]


কী কী রয়েছে তা আন্ডারস্কোরগুলিতে কীভাবে প্রয়োগ করা হয় ... সাবধান থাকুন যদি এটি ফিল্টারের ভিতরে সূচকের সমতুল্য হয় ... মোটেও সর্বোত্তম নয় ...
আলভারো জোয়াও

1

ফিল্টার + ইনডেক্সফ (আই 9 +):

function removeMany(array, indexes) {
  return array.filter(function(_, idx) {
    return indexes.indexOf(idx) === -1;
  });
}); 

অথবা ES6 ফিল্টার সহ + অনুসন্ধান (প্রান্ত +):

function removeMany(array, indexes = []) {
  return array.filter((_, idx) => indexes.indexOf(idx) === -1)
}

ফিল্টারটির ভিতরে সূচি ... সর্বোত্তম নয়
আলভারো


0

শব্দ শুনে মনে হচ্ছে প্রয়োগ হতে পারে আপনি যা খুঁজছেন।
সম্ভবত এই কিছু কাজ করবে?

Array.prototype.splice.apply(valuesArray, removeValFromIndexes );

তবে .splice()পদ্ধতিটি উপাদানগুলির একটি তালিকা অপসারণের প্রত্যাশা করে না, এটি এমন একটি উপাদানের একক সূচকের প্রত্যাশা করে যেখানে মুছে ফেলা শুরু করা যায় এবং তারপরে উপাদানগুলির সংখ্যা সরিয়ে নেওয়া যায় ...
nnnnnn

0

একাধিক আইটেম বা অনন্য আইটেম জন্য:

আমি আপনাকে অ্যারে.প্রোটোটাইপ.ফিল্টার ব্যবহার করার পরামর্শ দিচ্ছি

আপনি যদি ইতিমধ্যে সূচকটি জানেন তবে কখনই সূচিপত্র ব্যবহার করবেন না !:

var valuesArr = ["v1","v2","v3","v4","v5"];
var removeValFrom = [0, 2, 4];

valuesArr = valuesArr.filter(function(value, index) {
     return removeValFrom.indexOf(index) == -1;
}); // BIG O(N*m) where N is length of valuesArr and m is length removeValFrom

না:

হ্যাশ সহ ... অ্যারে.প্রোটোটাইপ.ম্যাপ ব্যবহার করে

  var valuesArr = ["v1","v2","v3","v4","v5"];
  var removeValFrom = {};
  ([0, 2, 4]).map(x=>removeValFrom[x]=1); //bild the hash.
  valuesArr = valuesArr.filter(function(value, index) {
      return removeValFrom[index] == 1;
  }); // BIG O(N) where N is valuesArr;

0
var valuesArr = new Array("v1","v2","v3","v4","v5");   
var removeValFromIndex = new Array(0,2,4);

console.log(valuesArr)
let arr2 = [];

for (let i = 0; i < valuesArr.length; i++){
  if (    //could also just imput this below instead of index value
    valuesArr[i] !== valuesArr[0] && // "v1" <--
    valuesArr[i] !== valuesArr[2] && // "v3" <--
    valuesArr[i] !== valuesArr[4]    // "v5" <--
  ){
    arr2.push(valuesArr[i]);
  }
}

console.log(arr2);

এইটা কাজ করে. তবে আপনি প্রক্রিয়াটিতে একটি নতুন অ্যারে তৈরি করবেন। Thats আপনি চান বা না চান তা নিশ্চিত নন, তবে প্রযুক্তিগতভাবে এটি এমন একটি অ্যারে হবে যা কেবলমাত্র আপনি চেয়েছিলেন মানগুলিই রাখে।


-1

আপনি চেষ্টা ও ব্যবহার করতে পারেন delete array[index]এটি সম্পূর্ণরূপে উপাদানটিকে সরাবে না বরং মানটিকে সেট করে undefined


ধন্যবাদ তবে আমি উপাদানগুলি অপসারণ করতে চাই।
xyz

-1

আপনি Setঅ্যারে থেকে একটি নির্মাণ করতে পারেন এবং তারপরে সেট থেকে একটি অ্যারে তৈরি করতে পারেন।

const array = [1, 1, 2, 3, 5, 5, 1];
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // Result: [1, 2, 3, 5]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.