জাভাস্ক্রিপ্টে অ্যারে.ম্যাপ সহ উপাদানগুলি সরানো


90

আমি map()ফাংশনটি ব্যবহার করে আইটেমগুলির একটি অ্যারে ফিল্টার করতে চাই । এখানে একটি কোড স্নিপেট:

var filteredItems = items.map(function(item)
{
    if( ...some condition... )
    {
        return item;
    }
});

সমস্যাটি হ'ল ফিল্টারযুক্ত আইটেমগুলি অ্যারেতে এখনও স্থান ব্যবহার করে এবং আমি সেগুলি পুরোপুরি মুছতে চাই।

কোন ধারণা?

সম্পাদনা: ধন্যবাদ, আমি ভুলে গিয়েছিলাম, আমি filter()যা চেয়েছিলাম তা আসলে একটি filter()তখন ক map()

EDIT2: যে ইশারা জন্য ধন্যবাদ map()এবং filter(), সব ব্রাউজারে বাস্তবায়িত হয়নি যদিও আমার নির্দিষ্ট কোড একটি ব্রাউজারে চলে উদ্দেশ্যে না হয়।


2 টি পুনরাবৃত্তি কেন 1 টির চেয়ে খারাপ বলে আপনি বিশদটি জানাতে পারেন? মানে, 2 * ও (এন) আমার কাছে ও (2 * এন) এর সমতুল্য ...
ভিনসেন্ট রবার্ট

উত্তর:


105

filterফিল্টারিংয়ের পাশাপাশি অ্যারেতে থাকা আইটেমগুলিকে পরিবর্তন করতে না চাইলে আপনার মানচিত্রের পরিবর্তে পদ্ধতিটি ব্যবহার করা উচিত ।

যেমন

var filteredItems = items.filter(function(item)
{
    return ...some condition...;
});

[সম্পাদনা করুন: অবশ্যই আপনি সবসময় sourceArray.filter(...).map(...)ফিল্টার এবং মিউটেট উভয়কেই করতে পারেন]


4
mapরূপান্তরিত হয় না
আপনাকে ধন্যবাদ

14
কিন্তু আপনি পরিবর্তন করতে পারেন map
ক্রেজিওয়াকো

এটির সাথে যত্নশীল: জেএস যখন রেফারেন্সটি পাস করে আপনি যখন মানচিত্রের সাথে কোনও কিছুর পরিবর্তন করবেন তখন এটি বস্তুটি পরিবর্তন করবে তবে এমডিএন দাঁড়িয়ে আছে, মানচিত্রগুলি পরিবর্তিত অ্যারে ফিরিয়ে দেয়।
alexOtano

4
কীভাবে ফিল্টার করবেন প্রশ্নটি জিজ্ঞাসা করেনি, প্রশ্নটি কীভাবে মানচিত্রে মুছতে হবে
ড্যাজলে

4
@alexOtano না, মানচিত্রটি রূপান্তরিত করে না এবং রূপান্তরিত অ্যারেটি ফিরিয়ে দেয় না। এটি একটি নতুন অ্যারে প্রদান করে। যেমন,x=[1,2,3];y = x.map(z => z*2);console.log(x,y);
কাইল বেকার

40

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

এটি বলেছিল, টিএল; ডাঃ এটি: আপনি যা চেয়েছেন তা সম্পাদন করতে (এক ফাংশন কলের মধ্যে ফিল্টারিং এবং ম্যাপিং), আপনি ব্যবহার করবেনArray.reduce()

তবে, আরও পঠনযোগ্য এবং (কম গুরুত্বপূর্ণভাবে) সাধারণত উল্লেখযোগ্যভাবে দ্রুত 2 পদ্ধতির মধ্যে রয়েছে কেবল ফিল্টার এবং মানচিত্রকে এক সাথে বেঁধে রাখা:

[1,2,3].filter(num => num > 2).map(num => num * 2)

নিম্নলিখিতটি কীভাবে Array.reduce()কাজ করে তার বর্ণনা এবং এটি কীভাবে এক পুনরাবৃত্তিতে ফিল্টার এবং মানচিত্র সম্পাদন করতে ব্যবহার করা যেতে পারে is আবার, যদি এটি খুব ঘনীভূত হয় তবে আমি উপরের লিঙ্কযুক্ত ব্লগ পোস্টটি দেখার জন্য অত্যন্ত পরামর্শ দিচ্ছি, এটি স্পষ্ট উদাহরণ এবং অগ্রগতির সাথে অনেক বেশি বন্ধুত্বপূর্ণ পরিচয়।


আপনি একটি যুক্তি হ্রাস করুন যা একটি (সাধারণত বেনামে) ফাংশন।

সেই বেনামি ফাংশনটি দুটি পরামিতি নেয় - একটি (মানচিত্র / ফিল্টার / forEach এ অজ্ঞাতনামা ফাংশনগুলির মত) চালিত হওয়া পুনরুক্তি। বেনামে ফাংশনটি হ্রাস করতে পাস করার জন্য আরও একটি যুক্তি রয়েছে, তবে those ফাংশনগুলি গ্রহণ করে না, এবং এটি সেই মান যা ফাংশন কলগুলির মধ্যে পাশ করা হবে, প্রায়শই মেমো হিসাবে পরিচিত

নোট করুন যে অ্যারে.ফিল্টার () শুধুমাত্র একটি যুক্তি (একটি ফাংশন) নিলে, অ্যারে.রেডুস () এছাড়াও একটি গুরুত্বপূর্ণ (যদিও alচ্ছিক) দ্বিতীয় যুক্তি গ্রহণ করে: 'মেমো' এর জন্য একটি প্রাথমিক মান যা সেই বেনামে ফাংশনে চলে যাবে প্রথম যুক্তি, এবং পরবর্তীকালে ফাংশন কলগুলির মধ্যে রূপান্তরিত এবং পাশ করা যায়। (যদি এটি সরবরাহ না করা হয়, তবে প্রথম বেনাম ফাংশন কলের 'মেমো' ডিফল্টরূপে প্রথম পুনরাবৃত্ত হবে এবং 'পুনরাবৃত্তি' যুক্তিটি অ্যারেতে দ্বিতীয় মান হবে)

আমাদের ক্ষেত্রে, আমরা শুরু করতে একটি খালি অ্যারে পাস করব, এবং তারপরে আমাদের পুনরাবৃত্তিকে আমাদের অ্যারেতে ইনজেক্ট করতে হবে বা আমাদের ফাংশনের উপর ভিত্তি করে নয় তা বেছে নেব - এটি ফিল্টারিং প্রক্রিয়া।

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

এটি ফিল্টার এবং মানচিত্রকে এক পুনরাবৃত্তিতে ঘটতে দেয়, আমাদের প্রয়োজনীয় পুনরাবৃত্তির অর্ধেক অংশ কেটে দেয় - প্রতিটি পুনরাবৃত্তির দ্বিগুণ কাজ করে যদিও, জাভাস্ক্রিপ্টে এত ব্যয়বহুল নয় এমন ফাংশন কল ব্যতীত অন্য কিছুই সংরক্ষণ করা যায় না which ।

আরও সম্পূর্ণ ব্যাখ্যার জন্য, MDN ডক্স (বা এই উত্তরটির শুরুতে উল্লেখ করা আমার পোস্টে) দেখুন।

হ্রাস কলের মূল উদাহরণ:

let array = [1,2,3];
const initialMemo = [];

array = array.reduce((memo, iteratee) => {
    // if condition is our filter
    if (iteratee > 1) {
        // what happens inside the filter is the map
        memo.push(iteratee * 2); 
    }

    // this return value will be passed in as the 'memo' argument
    // to the next call of this function, and this function will have
    // every element passed into it at some point.
    return memo; 
}, initialMemo)

console.log(array) // [4,6], equivalent to [(2 * 2), (3 * 2)]

আরও সংক্ষিপ্ত সংস্করণ:

[1,2,3].reduce((memo, value) => value > 1 ? memo.concat(value * 2) : memo, [])

লক্ষ্য করুন যে প্রথম পুনরুক্তি একের চেয়ে বড় নয় এবং তাই ফিল্টার করা হয়েছিল। কেবলমাত্র তার অস্তিত্বকে পরিষ্কার করার জন্য এবং এর দিকে দৃষ্টি আকর্ষণ করার জন্য নামযুক্ত প্রাথমিক মেমোটি নোট করুন। আবার এটি প্রথম বেনাম ফাংশন কলে 'মেমো' হিসাবে প্রেরণ করা হয় এবং তারপরে বেনামে ফাংশনটির ফিরে আসা মান পরবর্তী ফাংশনে 'মেমো' যুক্তি হিসাবে প্রেরণ করা হয়।

মেমোটির জন্য ক্লাসিক ব্যবহারের ক্ষেত্রে আরেকটি উদাহরণ একটি অ্যারের মধ্যে সবচেয়ে ছোট বা বৃহত্তম সংখ্যাটি ফিরিয়ে আনবে। উদাহরণ:

[7,4,1,99,57,2,1,100].reduce((memo, val) => memo > val ? memo : val)
// ^this would return the largest number in the list.

আপনার নিজের হ্রাস ফাংশনটি কীভাবে লিখবেন তার একটি উদাহরণ (এটি প্রায়শই এই জাতীয় ফাংশনগুলি বোঝার জন্য সহায়তা করে)

test_arr = [];

// we accept an anonymous function, and an optional 'initial memo' value.
test_arr.my_reducer = function(reduceFunc, initialMemo) {
    // if we did not pass in a second argument, then our first memo value 
    // will be whatever is in index zero. (Otherwise, it will 
    // be that second argument.)
    const initialMemoIsIndexZero = arguments.length < 2;

    // here we use that logic to set the memo value accordingly.
    let memo = initialMemoIsIndexZero ? this[0] : initialMemo;

    // here we use that same boolean to decide whether the first
    // value we pass in as iteratee is either the first or second
    // element
    const initialIteratee = initialMemoIsIndexZero ? 1 : 0;

    for (var i = initialIteratee; i < this.length; i++) {
        // memo is either the argument passed in above, or the 
        // first item in the list. initialIteratee is either the
        // first item in the list, or the second item in the list.
           memo = reduceFunc(memo, this[i]);
        // or, more technically complete, give access to base array
        // and index to the reducer as well:
        // memo = reduceFunc(memo, this[i], i, this);
    }

    // after we've compressed the array into a single value,
    // we return it.
    return memo;
}

প্রকৃত বাস্তবায়ন সূচকের মতো জিনিসগুলিতে অ্যাক্সেসের অনুমতি দেয়, উদাহরণস্বরূপ, তবে আমি আশা করি এটি আপনাকে এর সংক্ষিপ্তসার জন্য একটি জটিল জটিলতা পেতে সহায়তা করবে।


4
উজ্জ্বল! আমি বছরের পর বছর ধরে এই জাতীয় কিছু করতে চাইছিলাম। চেষ্টা করার চেষ্টা করে একটি সুন্দর এবং উপায় এবং বাহ, প্রাকৃতিক জাভাস্ক্রিপ্ট বের করার সিদ্ধান্ত নিয়েছে!
জিমিলোই

আরেকটি উপযোগিতা reduceযে অসদৃশ হয় filter+ + map, কলব্যাক একটি সূচক যুক্তি মূল অ্যারের সূচক, এবং ফিল্টার করা যে নয় যে প্রেরণ করা সম্ভব।
কংগসবঙ্গাস

@ কাইলবেকার আপনার ব্লগ পোস্টের লিঙ্কটি খুঁজে পাওয়া যায় না এমন একটি পৃষ্ঠায় যায়। আপনি দয়া করে লিঙ্কটি আপডেট করতে পারেন? ধন্যবাদ!
টিম ফিলিপ

10

মানচিত্র যা তা করে না। আপনি সত্যই অ্যারে.ফিল্টার চান । অথবা আপনি যদি সত্যিই মূল তালিকা থেকে উপাদানগুলি সরাতে চান তবে আপনাকে লুপের জন্য এটি জরুরীভাবে করতে হবে।


6

অ্যারে ফিল্টার পদ্ধতি

var arr = [1, 2, 3]

// ES5 syntax
arr = arr.filter(function(item){ return item != 3 })

// ES2015 syntax
arr = arr.filter(item => item != 3)

console.log( arr )


4
আপনি এটি করতেও পারেনvar arr = [1,2,"xxx", "yyy"]; arr = arr.filter(function(e){ return e!="xxx" }) console.log(arr)
জ্যাক ফাঁকা

আপনি বিশাল টেক্সট যুক্ত করতে 4 বছর পরে ফিরে এসেছেন? মাইনাস এক
আপনাকে ধন্যবাদ Thank

@ ব্যবহারকারী 633183 আপনি কার কথা উল্লেখ করছেন? কি "বিশাল পাঠ্য"? আপনার মন্তব্য অস্পষ্ট। আপনি কি নিশ্চিত যে আপনি সঠিক জায়গায় মন্তব্য করছেন ...?
vsync

2

আপনার অবশ্যই অবশ্যই লক্ষ্য রাখতে হবে যে Array.filterসমস্ত ব্রাউজারে এটি সমর্থিত নয়, আপনাকে অবশ্যই প্রোটোটাইপ করতে হবে:

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
    Array.prototype.filter = function(fun /*, thisp*/)
    {
        var len = this.length;

        if (typeof fun != "function")
            throw new TypeError();

        var res = new Array();
        var thisp = arguments[1];

        for (var i = 0; i < len; i++)
        {
            if (i in this)
            {
                var val = this[i]; // in case fun mutates this

                if (fun.call(thisp, val, i, this))
                   res.push(val);
            }
        }

        return res;
    };
}

এবং এটি করে আপনি আপনার যে কোনও পদ্ধতির দরকার পড়তে পারেন prot


4
আপনি কি সত্যিই এই পদ্ধতি polyfill করতে চান তাহলে, একটি সঠিক polyfill মত একটি লাইব্রেরি ব্যবহার করুন, অথবা এখনো ভাল Modernizr । অন্যথায়, আপনি সম্ভবত অস্পষ্ট ব্রাউজারগুলির সাথে বিভ্রান্তিকর বাগগুলিতে চলে যাবেন যেগুলি তারা দীর্ঘদিন ধরে উত্পাদন না হওয়া অবধি বুঝতে পারবেন না।
কাইল বেকার 21 '

0

নিম্নলিখিত বিবৃতি মানচিত্র ফাংশন ব্যবহার করে বস্তু পরিষ্কার করে।

var arraytoclean = [{v:65, toberemoved:"gronf"}, {v:12, toberemoved:null}, {v:4}];
arraytoclean.map((x,i)=>x.toberemoved=undefined);
console.dir(arraytoclean);

0

আমি কেবল অ্যারে ছেদটি লিখেছি যা সঠিকভাবে ডুপ্লিকেটগুলিও পরিচালনা করে

https://gist.github.com/gkucmierz/8ee04544fa842411f7553ef66ac2fcf0

// array intersection that correctly handles also duplicates

const intersection = (a1, a2) => {
  const cnt = new Map();
  a2.map(el => cnt[el] = el in cnt ? cnt[el] + 1 : 1);
  return a1.filter(el => el in cnt && 0 < cnt[el]--);
};

const l = console.log;
l(intersection('1234'.split``, '3456'.split``)); // [ '3', '4' ]
l(intersection('12344'.split``, '3456'.split``)); // [ '3', '4' ]
l(intersection('1234'.split``, '33456'.split``)); // [ '3', '4' ]
l(intersection('12334'.split``, '33456'.split``)); // [ '3', '3', '4' ]


0

প্রথমে আপনি মানচিত্রটি ব্যবহার করতে পারেন এবং শৃঙ্খলার সাহায্যে আপনি ফিল্টারটি ব্যবহার করতে পারেন

state.map(item => {
            if(item.id === action.item.id){   
                    return {
                        id : action.item.id,
                        name : item.name,
                        price: item.price,
                        quantity : item.quantity-1
                    }

            }else{
                return item;
            }
        }).filter(item => {
            if(item.quantity <= 0){
                return false;
            }else{
                return true;
            }
        });
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.