ফিল্টার ফাংশন দ্বারা একটি অ্যারের ভাগ করা


92

আমি একটি জাভাস্ক্রিপ্ট অ্যারে যে আমি দুই একটি ফাংশন প্রতিটি উপাদান দেখায় আহ্বান কিনা উপর ভিত্তি করে বিভক্ত করতে চাই আছে trueবা false। মূলত, এটি একটি array.filter, তবে আমি যে উপাদানগুলি ফিল্টার করে ফেলেছি তাও হাতে রাখতে চাই ।

বর্তমানে, আমার পরিকল্পনাটি array.forEachপ্রতিটি উপাদানটিতে প্রাকটিক্যাল ফাংশনটি ব্যবহার এবং কল করা। এটি সত্য বা মিথ্যা কিনা তার উপর নির্ভর করে, আমি বর্তমান উপাদানটিকে দুটি নতুন অ্যারের মধ্যে একটিতে চাপ দেব। এটি করার জন্য আরও কি মার্জিত বা অন্য কোনও ভাল উপায় আছে? একটি array.filterযেখানে অন্য অ্যারের সম্মুখের উপাদান ধাক্কা আগেই ফেরৎ হবে false, উদাহরণস্বরূপ?


আপনি যদি কিছু নমুনা কোড পোস্ট করতে পারেন তবে আপনাকে আরও ভাল উত্তর দিতে সাহায্য করবে!
মার্ক পাইসাক - ট্রিলন.ও

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

4
আপনি কলব্যাকটি যা যা করতে পেরেছেন তা করতে পারেন .filterতবে এই জাতীয় পার্শ্ব প্রতিক্রিয়াগুলি ট্র্যাক করা এবং বুঝতে অসুবিধা হয়। অ্যারের উপরে কেবল পুনরাবৃত্তি করুন এবং একটি অ্যারে বা অন্যটিতে চাপুন।
ফেলিক্স ক্লিং

উত্তর:


76

ES6 এর সাহায্যে আপনি হ্রাস সহ স্প্রেড সিনট্যাক্সটি ব্যবহার করতে পারেন:

function partition(array, isValid) {
  return array.reduce(([pass, fail], elem) => {
    return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]];
  }, [[], []]);
}

const [pass, fail] = partition(myArray, (e) => e > 5);

বা একক লাইনে:

const [pass, fail] = a.reduce(([p, f], e) => (e > 5 ? [[...p, e], f] : [p, [...f, e]]), [[], []]);

8
আমার জন্য, লোডাশ বিভাজন বা কেবলমাত্র প্রত্যেকের জন্য বোঝা আরও সহজ হবে, তবে তবুও সুন্দর চেষ্টা
টনি লেই

15
এটি আসল প্রতিটি উপাদানের জন্য দুটি নতুন অ্যারে তৈরি করবে। একটি অ্যারেতে কেবল দুটি উপাদান থাকবে, অন্যটি অ্যারের আকারের সাথে বৃদ্ধি পাবে। এটি এইভাবে সুপার ধীর এবং প্রচুর মেমরির অপচয় করবে। (আপনি এটি একটি ধাক্কা
দিয়েও

ধন্যবাদ, আমার সময় সাশ্রয়!
7urkm3n

এটি সত্যিই দরকারী, ব্রেজা। অন্যদের জন্য নোট: নীচে আরও কয়েকটি পাঠযোগ্য সংস্করণ রয়েছে।
রাফি

38

আপনি লড্যাশ. পার্টিশন ব্যবহার করতে পারেন

var users = [
  { 'user': 'barney',  'age': 36, 'active': false },
  { 'user': 'fred',    'age': 40, 'active': true },
  { 'user': 'pebbles', 'age': 1,  'active': false }
];

_.partition(users, function(o) { return o.active; });
// → objects for [['fred'], ['barney', 'pebbles']]

// The `_.matches` iteratee shorthand.
_.partition(users, { 'age': 1, 'active': false });
// → objects for [['pebbles'], ['barney', 'fred']]

// The `_.matchesProperty` iteratee shorthand.
_.partition(users, ['active', false]);
// → objects for [['barney', 'pebbles'], ['fred']]

// The `_.property` iteratee shorthand.
_.partition(users, 'active');
// → objects for [['fred'], ['barney', 'pebbles']]

বা ramda.partition

R.partition(R.contains('s'), ['sss', 'ttt', 'foo', 'bars']);
// => [ [ 'sss', 'bars' ],  [ 'ttt', 'foo' ] ]

R.partition(R.contains('s'), { a: 'sss', b: 'ttt', foo: 'bars' });
// => [ { a: 'sss', foo: 'bars' }, { b: 'ttt' }  ]

16

আপনি এটির জন্য হ্রাস ব্যবহার করতে পারেন:

function partition(array, callback){
  return array.reduce(function(result, element, i) {
    callback(element, i, array) 
      ? result[0].push(element) 
      : result[1].push(element);

        return result;
      }, [[],[]]
    );
 };

হালনাগাদ. ES6 সিনট্যাক্স ব্যবহার করে আপনি এটি পুনরাবৃত্তি ব্যবহার করে করতে পারেন:

function partition([current, ...tail], f, [left, right] = [[], []]) {
    if(current === undefined) {
        return [left, right];
    }
    if(f(current)) {
        return partition(tail, f, [[...left, current], right]);
    }
    return partition(tail, f, [left, [...right, current]]);
}

4
আইএমএইচও, প্রথম সমাধান (ধাক্কা) অ্যারের আকার বাড়ার সাথে সাথে আরও ভাল পারফরম্যান্স।
টুলমেকারস্টেভ

আপনি কীভাবে আরও বেশি ব্যাখ্যা করতে পারেন? আমি উপরের উত্তরের মন্তব্যটি পড়েছি তবে এখনও বিভ্রান্ত কেন
বুঞ্চিস

4
@ বুন্সিস প্রথম পদ্ধতির প্রতিটি উপাদানকে একবারে পরীক্ষা করে, কেবলমাত্র সেই উপাদানটিকে উপযুক্ত অ্যারেতে চাপানো। দ্বিতীয় পদ্ধতির গঠন [...left, current]বা [...right, current]- প্রতিটি উপাদানগুলির জন্য। আমি সঠিক ইন্টার্নালগুলি জানি না, তবে আমি নিশ্চিত যে কোনও উপাদানকে অ্যারেতে চাপিয়ে দেওয়ার চেয়ে নির্মাণ আরও ব্যয়বহুল। এছাড়াও, একটি সাধারণ নিয়ম হিসাবে, পুনরাবৃত্তির চেয়ে বেশি ব্যয়বহুল iterating , কারণ এটি একটি "স্ট্যাক ফ্রেম" প্রতিটি সময় তৈরি জড়িত।
টুলমেকারস্টেভ

14

এটি রুবির সাথে খুব মিল বলে মনে হচ্ছেEnumerable#partition পদ্ধতির ।

যদি ফাংশনটির পার্শ্ব-প্রতিক্রিয়া না ঘটে (যেমন, এটি মূল অ্যারে পরিবর্তন করতে পারে না), তবে প্রতিটি উপাদানকে পুনরুক্ত করে এবং উপাদানটিকে আপনার দুটি অ্যারেতে চাপ দেওয়ার চেয়ে অ্যারে বিভাজন করার আর কোনও কার্যকর উপায় নেই।

বলা হচ্ছে, Arrayএই ফাংশনটি সম্পাদন করার জন্য একটি পদ্ধতি তৈরি করা যুক্তিযুক্তভাবে আরও "মার্জিত" । এই উদাহরণে, ফিল্টার ফাংশনটি মূল অ্যারে (যেমন, thisমূল অ্যারে হবে) এর প্রসঙ্গে কার্যকর করা হয় এবং এটি উপাদানটির উপাদান এবং সূচকটিকেeach আর্গুমেন্ট হিসাবে ( জিউকিউরির পদ্ধতির অনুরূপ ) গ্রহণ করে:

Array.prototype.partition = function (f){
  var matched = [],
      unmatched = [],
      i = 0,
      j = this.length;

  for (; i < j; i++){
    (f.call(this, this[i], i) ? matched : unmatched).push(this[i]);
  }

  return [matched, unmatched];
};

console.log([1, 2, 3, 4, 5].partition(function (n, i){
  return n % 2 == 0;
}));

//=> [ [ 2, 4 ], [ 1, 3, 5 ] ]

11
আধুনিক পাঠকের জন্য, দয়া করে বৈশ্বিক স্ট্যান্ডার্ড লাইব্রেরি অবজেক্টগুলিতে পদ্ধতি যুক্ত করবেন না। এটি বিপজ্জনক, এবং সম্ভবত ওভাররাইট করা সম্ভবত রহস্যজনক এবং ভাঙ্গা আচরণের দিকে পরিচালিত করে। একটি সরল পুরাতন ফাংশন, সঠিকভাবে স্কোপ করা আরও নিরাপদ এবং মাইফঙ্ক (অ্যারে) কল করা অ্যারে.মাইফুনক () এর চেয়ে কম "মার্জিত" নয়।
এমমেট আর।

14

আমি এই ছোট্ট লোকটির সাথে এসেছি। এটি আপনার বর্ণিত প্রত্যেকটির জন্য ব্যবহার করে তবে এটি আমার মতে পরিষ্কার এবং সংযুক্ত বলে মনে হচ্ছে।

//Partition function
function partition(array, filter) {
  let pass = [], fail = [];
  array.forEach((e, idx, arr) => (filter(e, idx, arr) ? pass : fail).push(e));
  return [pass, fail];
}

//Run it with some dummy data and filter
const [lessThan5, greaterThanEqual5] = partition([0,1,4,3,5,7,9,2,4,6,8,9,0,1,2,4,6], e => e < 5);

//Output
console.log(lessThan5);
console.log(greaterThanEqual5);


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

আমি এর সরলতা এবং কমনীয়তার জন্য এটি খুব পছন্দ করি। এটি বলার পরে, আমি এটি for@Qwertymk দ্বারা পুরানো উত্তরের মতো একটি সাধারণ লুপের চেয়ে উল্লেখযোগ্যভাবে ধীর বলে মনে করেছি। যেমন 100,000 উপাদান রয়েছে এমন অ্যারের জন্য এটি আমার সিস্টেমে দ্বিগুণ slow
ট্রাম্পি

9

ফিল্টার ফাংশনে আপনি আপনার ভুয়া আইটেমগুলিকে অন্য পরিবর্তনশীল বাহিরের কার্যে ঠেলাতে পারেন:

var bad = [], good = [1,2,3,4,5];
good = good.filter(function (value) { if (value === false) { bad.push(value) } else { return true});

অবশ্যই value === falseবাস্তব তুলনা করা দরকার;)

তবে এটি প্রায় একই অপারেশনটি করে forEach। আমি মনে করি আপনার forEachআরও ভাল কোড পঠনযোগ্যতার জন্য ব্যবহার করা উচিত ।


উপরের পোস্টারের সাথে একমত ... ফিল্টার ফাংশনে এই ধরণের লজিক লাগানো কিছুটা পুষ্পযুক্ত এবং পরিচালনা করা শক্ত বোধ করে।
দ্যুউটারসাইড

আমার মনে হয় ফিল্টারটি বোধগম্য হয়েছে, আপনি এগুলিকে মূল অ্যারে থেকে মুছতে চান যাতে এটি ফিল্টার হয়
মোজিমি

5

একটি পড়া সহজ।

const partition = (arr, condition) => {
    const trues = arr.filter(el => condition(el));
    const falses = arr.filter(el => !condition(el));
    return [trues, falses];
};

// sample usage
const nums = [1,2,3,4,5,6,7]
const [evens, odds] = partition(nums, (el) => el%2 == 0)

6
খারাপ দিকটি হ'ল আপনি কেবল তার পরিবর্তে 2 টি লুপ করেন
লরেন্ট

পাঠ্যতার জন্য উত্সাহ দিন, ছোট অ্যারেতে এটি আরও ভবিষ্যতের প্রমাণ
অ্যালান.সিমন

4

এটা চেষ্টা কর:

function filter(a, fun) {
    var ret = { good: [], bad: [] };
    for (var i = 0; i < a.length; i++)
        if (fun(a[i])
            ret.good.push(a[i]);
        else
            ret.bad.push(a[i]);
    return ret;
}

ডেমো


নির্দেশ করে যে অ্যারেগুলির ফিল্টার ফাংশনটি আসলে সমস্ত ব্রাউজারগুলিতে সমর্থিত নয় (আমি আপনাকে ওল্ডার IEs এ দেখছি)
TheZ

4

এই সম্পর্কে কি?

[1,4,3,5,3,2].reduce( (s, x) => { s[ x > 3 ].push(x); return s;} , {true: [], false:[]} )

সম্ভবত স্প্রেড অপারেটর এটি আরও দক্ষ

বা কিছুটা খাটো, তবে কৃপণ

[1,4,3,5,3,2].reduce( (s, x) => s[ x > 3 ].push(x)?s:s , {true: [], false:[]} )


2

এখানে প্রচুর উত্তর Array.prototype.reduceএকটি পরিবর্তনীয় সঞ্চালক তৈরি করতে ব্যবহার করে, এবং যথাযথভাবে উল্লেখ করতে হবে যে বড় অ্যারেগুলির জন্য, এটি বলার চেয়ে আরও দক্ষ, বলুন, প্রতিটি পুনরাবৃত্তিকে একটি নতুন অ্যারে অনুলিপি করতে একটি স্প্রেড অপারেটর ব্যবহার করে। অবক্ষয়টি হ'ল এটি সংক্ষিপ্ত ল্যাম্বদা সিনট্যাক্স ব্যবহার করে "খাঁটি" এক্সপ্রেশন হিসাবে অতটা সুন্দর নয়।

তবে এর একটি উপায় কমা অপারেটরটি ব্যবহার করা। সি-জাতীয় ভাষায়, কমা হ'ল একটি অপারেটর যা সর্বদা ডান হাতের অপারেন্ডকে ফেরত দেয়। আপনি এটি ব্যবহার করতে পারেন এমন অভিব্যক্তি তৈরি করতে যা শূন্য ফাংশনটিকে কল করে এবং একটি মান দেয়।

function partition(array, predicate) {
    return array.reduce((acc, item) => predicate(item)
        ? (acc[0].push(item), acc)
        : (acc[1].push(item), acc), [[], []]);
}

আপনি যদি এই সত্যটির সদ্ব্যবহার করেন যে কোনও বুলিয়ান অভিব্যক্তিটি স্পষ্টভাবে 0 এবং 1 হিসাবে একটি সংখ্যায় কাস্ট করে, এবং আপনি এটিকে আরও সংক্ষিপ্ত করে তুলতে পারেন, যদিও আমি মনে করি এটি পাঠযোগ্য নয়:

function partition(array, predicate) {
    return array.reduce((acc, item) => (acc[+!predicate(item)].push(item), acc), [[], []]);
}

ব্যবহার:

const [trues, falses] = partition(['aardvark', 'cat', 'apple'], i => i.startsWith('a'));
console.log(trues); // ['aardvark', 'apple']
console.log(falses); // ['cat']

0

এক-লাইন পার্টিশন

const partition = (a,f)=>a.reduce((p,q)=>(p[+!f(q)].push(q),p),[[],[]]);

ডেমো

// to make it consistent to filter pass index and array as arguments
const partition = (a, f) =>
    a.reduce((p, q, i, ar) => (p[+!f(q, i, ar)].push(q), p), [[], []]);

console.log(partition([1, 2, 3, 4, 5], x => x % 2 === 0));
console.log(partition([..."ABCD"], (x, i) => i % 2 === 0));

প্রকারের জন্য

const partition = <T>(
  a: T[],
  f: (v: T, i?: number, ar?: T[]) => boolean
): [T[], T[]] =>
  a.reduce((p, q, i, ar) => (p[+!f(q, i, ar)].push(q), p), [[], []]);

-1

আমি এটি করা শেষ করেছি কারণ এটি বোঝা সহজ (এবং পুরোপুরি টাইপস্ক্রিপ্ট দিয়ে টাইপ করা হয়েছে)।

const partition = <T>(array: T[], isValid: (element: T) => boolean): [T[], T[]] => {
  const pass: T[] = []
  const fail: T[] = []
  array.forEach(element => {
    if (isValid(element)) {
      pass.push(element)
    } else {
      fail.push(element)
    }
  })
  return [pass, fail]
}

// usage
const [pass, fail] = partition([1, 2, 3, 4, 5], (element: number) => element > 3)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.