কিভাবে প্রাথমিক বিরতি হ্রাস () পদ্ধতি?


94

আমি reduce()পদ্ধতিটির পুনরাবৃত্তিটি কীভাবে ভাঙ্গতে পারি ?

for:

for (var i = Things.length - 1; i >= 0; i--) {
  if(Things[i] <= 0){
    break;
  }
};

reduce()

Things.reduce(function(memo, current){
  if(current <= 0){
    //break ???
    //return; <-- this will return undefined to memo, which is not what I want
  }
}, 0)

currentউপরের কোডে কী আছে ? এগুলি কীভাবে একই জিনিস করতে পারে তা আমি দেখতে পাচ্ছি না। কোন ক্ষেত্রে সেখানে পদ্ধতি গোড়ার দিকে মত বিরতি হয় some, every,find
elclanrs

someএবং everyবুলেটিয়ানগুলি ফিরে আসুন এবং findএকটি একক রেকর্ড ফিরিয়ে দিন, আমি যা চাই তা হল একটি মেমো উত্পন্ন করার জন্য অপারেশন চালানো। currentবর্তমানের মান। রেফারেন্স
জুলিও মেরিন্স

মানে currentকোডের প্রথম টুকরোতে কী আছে?
এলক্ল্যানাররা

আপডেট হয়েছে, উত্তরের জন্য ধন্যবাদ
জুলিও মেরিন্স

4
উত্তরটি হ'ল আপনি তাড়াতাড়ি ভাঙতে পারবেন না reduce, আপনাকে বিল্টিন ফাংশনগুলির সাথে অন্য কোনও উপায় খুঁজে বের করতে হবে যা তাড়াতাড়ি প্রস্থান করে বা আপনার নিজস্ব সহায়ক তৈরি করতে পারে, বা লড্যাশ বা কোনও কিছু ব্যবহার করতে পারে। আপনি যা করতে চান তার একটি সম্পূর্ণ উদাহরণ পোস্ট করতে পারেন?
এলক্লানাররা

উত্তর:


94

হালনাগাদ

কিছু ভাষ্যকার একটি ভাল বক্তব্য রেখেছেন যে .reduce()যুক্তির ভিতরে তাড়াতাড়ি ভাঙতে মূল অ্যারেটি পরিবর্তন করা হচ্ছে ।

অতএব, আমি মূল অ্যারেটির একটি অনুলিপি উত্সাহিত করার আগে একটি অনুবর্তন পদক্ষেপ কল করার আগে একটি যুক্ত করে উত্তরটি কিছুটা সংশোধন করেছি । দ্রষ্টব্য : একই কার্য সম্পাদনকারী অনুরূপ অপগুলি হ'ল (কম স্পষ্ট) এবং স্প্রেড অপারেটর ( কিছুটা কম পারফর্মেন্ট )। মনে রাখবেন, এগুলি সমস্ত সামগ্রিক রানটাইম + 1 * (ও (1)) এ রৈখিক সময়ের অতিরিক্ত ধ্রুবক ফ্যাক্টর যুক্ত করে।.slice(0).reduce()slice()[...array]

অনুলিপিটি শেষ রূপান্তর থেকে মূল অ্যারেটি সংরক্ষণ করে যা পুনরাবৃত্তি থেকে ইজেকশন সৃষ্টি করে।

const array = ['9', '91', '95', '96', '99'];
const x = array
    .slice(0)                         // create copy of "array" for iterating
    .reduce((acc, curr, i, arr) => {
       if (i === 2) arr.splice(1);    // eject early by mutating iterated copy
       return (acc += curr);
    }, '');

console.log("x: ", x, "\noriginal Arr: ", array);
// x:  99195
// original Arr:  [ '9', '91', '95', '96', '99' ]


ওল্ড

আপনি হ্রাস ফাংশনটির 4 র্থ যুক্তিটি পরিবর্তনের মাধ্যমে একটি .reduce () অনুরোধের যে কোনও পুনরাবৃত্তি ভাঙ্গতে পারেন: "অ্যারে"। কোনও কাস্টম হ্রাস ফাংশনের প্রয়োজন নেই। পরামিতিগুলির সম্পূর্ণ তালিকার জন্য ডক্স দেখুন .reduce()

অ্যারে.প্রোটোটাইপ.ড্রেস ((acc, curr, i, অ্যারে))

৪ র্থ যুক্তি হ'ল অ্যারেটি পুনরাবৃত্তি হচ্ছে।

const array = ['9', '91', '95', '96', '99'];
const x = array
.reduce((acc, curr, i, arr) => {
    if(i === 2) arr.splice(1);  // eject early
    return acc += curr;
  }, '');
console.log('x: ', x);  // x:  99195

কেন ?:

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

কেন না?

এটি একটি খারাপ অনুশীলন হিসাবে ফাংশন পরামিতিগুলিকে পরিবর্তন না করার জন্য যুক্তিগুলির একটি সম্পূর্ণ তালিকা রয়েছে।


4
+1 এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এবং তবুও এই সমাধানটি কখনই ব্যবহার করা উচিত নয়, "কেন নয়" এর অধীনে বর্ণিত কারণে।
jhndodo

4
এটি সত্যই খারাপ বিজ্ঞাপন, কারণ spliceএকটি দৃশ্যমান মিউটেশন সম্পাদন করে ( array)। কার্যকরী দৃষ্টান্ত অনুযায়ী আপনি ধারাবাহিকতা পাস করার শৈলীতে হ্রাস বা ডান-সহযোগী হ্রাস সহ অলস মূল্যায়নটি ব্যবহার করবেন d বা, একটি সহজ বিকল্প হিসাবে, কেবল সাধারণ পুনরাবৃত্তি।

অপেক্ষা কর! হ্রাস ফাংশনটির চতুর্থ যুক্তিটি পরিবর্তনের মাধ্যমে: "অ্যারে" কোনও সঠিক বক্তব্য নয়। এক্ষেত্রে এটি ঘটছে (উত্তরের উদাহরণে) কারণ এটির অ্যারেটি একক দৈর্ঘ্যের অ্যারে (প্রথম উপাদান) কাটা যখন এর ইতিমধ্যে সূচক 2 এ পৌঁছেছে , স্পষ্টত পরের বার, সূচক 3 এর জন্য এটি পুনরাবৃত্তি করার জন্য কোনও আইটেম পাবে না (যেমন আপনি দৈর্ঘ্যের অ্যারের মূল রেফারেন্স mutating হয় 1 )। আপনি যদি এমন একটি পপ সঞ্চালন করেন যা উত্স অ্যারেটিকে খুব পরিবর্তন করতে পারে তবে এর মধ্যে থামবে না (যদি আপনি দ্বিতীয় শেষ সূচকে না থাকেন)।
কৌশিক চ্যাটার্জী

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

4
আমি কোনও অযাচিত মিউটেশন এড়াতে স্প্রেড অপারেটরের কাছে পৌঁছনাকে পছন্দ করি, [... অ্যারে] .ড্রেস ()
এবললেস্ট

16

হ্রাস ব্যবহার করবেন না। সাধারণ পুনরাবৃত্তকারী (যেমন, ইত্যাদি) দিয়ে অ্যারেতে কেবল পুনরাবৃত্তি করুন এবং যখন আপনার শর্তটি পূরণ হয় তখন ব্রেকআপ হয়ে যান।


58
এখানে মজা কোথায়? :)
আলেকজান্ডার মিলস

4
@ আলেকজান্ডারমিলস সম্ভবত তিনি একজন অভিযুক্ত হতে পছন্দ করেন!
ডিম্পিয়াक्स

4
এই উত্তরটির এখানে 0 মান রয়েছে
ফেডারেশন

নিশ্চিত হলেন না কেন এটি বেশ কয়েকটি উত্সাহ পেয়েছে ... এটি কোনও উত্তর নয় যেহেতু ওপি জিজ্ঞাসা করল কীভাবে হ্রাস () থেকে খুব শীঘ্রই বিরতি নেবে .. এটি আপনার যখন বাঁকানোর সময় কিছুটা ব্যথা হয় তখন ডাক্তারের কাছে যাওয়ার মতো এবং ডাক্তার বলে আপনি উপর বাঁক না।
রিসোসেলাম

12

আপনি যতক্ষণ না ফেরতের মানটির বিষয়ে চিন্তা করেন না ততক্ষণ আপনি কিছু এবং প্রতিটি মত ফাংশন ব্যবহার করতে পারেন । কলব্যাকটি মিথ্যা প্রত্যাবর্তনের সময় প্রতিটি বিরতি ঘটে যখন কিছু সত্য হয়:

things.every(function(v, i, o) {
  // do stuff 
  if (timeToBreak) {
    return false;
  } else {
    return true;
  }
}, thisArg);

25
তবে যদি সে চেষ্টা করে থাকে reduceতবে সংজ্ঞা অনুসারে সে রিটার্নের মানটি যত্ন করে

4
@ তোরাজাবুরো — অবশ্যই, তবে আমি এটি ওপিতে ব্যবহার হচ্ছে না এবং ফলাফল পাওয়ার অন্যান্য উপায়ও নেই। ;-)
রবিজি

6

reduceঅকাল থেকে প্রস্থান করার জন্য অন্তর্নির্মিত সংস্করণটি পাওয়ার কোনও উপায় নেই ।

তবে আপনি হ্রাসের নিজস্ব সংস্করণ লিখতে পারেন যা লুপটি কখন ভাঙ্গা উচিত তা চিহ্নিত করার জন্য একটি বিশেষ টোকেন ব্যবহার করে।

var EXIT_REDUCE = {};

function reduce(a, f, result) {
  for (let i = 0; i < a.length; i++) {
    let val = f(result, a[i], i, a);
    if (val === EXIT_REDUCE) break;
    result = val;
  }
  return result;
}

একটি অ্যারের যোগফলের জন্য এটি ব্যবহার করুন তবে আপনি 99 এ আঘাত করলে প্রস্থান করুন:

reduce([1, 2, 99, 3], (a, b) => b === 99 ? EXIT_REDUCE : a + b, 0);

> 3

4
পছন্দসই আচরণটি অর্জন করতে আপনি অলস মূল্যায়ন বা সিপিএস ব্যবহার করতে পারেন :
স্ক্রিপ্টাম

এই উত্তরের প্রথম বাক্যটি ভুল। আপনি বিরতি পেতে পারেন, বিশদ জন্য নীচে আমার উত্তর দেখুন।
টবিবিয় রেক্স

4

অ্যারে.এভারি উচ্চ আদেশের পুনরাবৃত্তিটি ভেঙে ফেলার জন্য খুব প্রাকৃতিক প্রক্রিয়া সরবরাহ করতে পারে।

const product = function(array) {
    let accumulator = 1;
    array.every( factor => {
        accumulator *= factor;
        return !!factor;
    });
    return accumulator;
}
console.log(product([2,2,2,0,2,2]));
// 0


1

আপনি প্রতিটি কোডটি ভাঙ্গতে পারেন - এবং এইভাবে প্রতিটি পুনরুক্তিকারী প্রতিটি বিল্ড - একটি ব্যতিক্রম ছুঁড়ে দিয়ে:

function breakReduceException(value) {
    this.value = value
}

try {
    Things.reduce(function(memo, current) {
        ...
        if (current <= 0) throw new breakReduceException(memo)
        ...
    }, 0)
} catch (e) {
    if (e instanceof breakReduceException) var memo = e.value
    else throw e
}

6
এটি সম্ভবত সমস্ত উত্তরগুলির মধ্যে সবচেয়ে কম দক্ষ কার্যকর কার্যকর। চেষ্টা / ধরা বিদ্যমান প্রয়োগের প্রসঙ্গটি ভেঙে ফেলে এবং কার্যকর করে 'ধীর পথে' falls ভি 8 কভারগুলির অধীনে যে কোনও অপ্টিমাইজেশানকে বিদায় জানায়।
ইভান প্লেইস

4
যথেষ্ট চরম নয়। এটি সম্পর্কে কীভাবে:if (current <= 0) window.top.close()
ব্যবহারকারীর 576ininstatemonica8

0

হিসাবে promiseগুলি আছে resolveএবং rejectকলব্যাক যুক্তি আমি তৈরি reduceসঙ্গে কার্যসংক্রান্ত ফাংশন breakকলব্যাক যুক্তি। এটি নেটিভ reduceপদ্ধতি হিসাবে সমস্ত একই আর্গুমেন্ট গ্রহণ করে , প্রথমটিতে কাজ করার জন্য অ্যারে ছাড়া (বানরের প্যাচিং এড়ান) except তৃতীয় [২] initialValueযুক্তি alচ্ছিক। functionরিডিউসারের জন্য নীচে স্নিপেট দেখুন ।

var list = ["w","o","r","l","d"," ","p","i","e","r","o","g","i"];

var result = reducer(list,(total,current,index,arr,stop)=>{
  if(current === " ") stop(); //when called, the loop breaks
  return total + current;
},'hello ');

console.log(result); //hello world

function reducer(arr, callback, initial) {
  var hasInitial = arguments.length >= 3;
  var total = hasInitial ? initial : arr[0];
  var breakNow = false;
  for (var i = hasInitial ? 0 : 1; i < arr.length; i++) {
    var currentValue = arr[i];
    var currentIndex = i;
    var newTotal = callback(total, currentValue, currentIndex, arr, () => breakNow = true);
    if (breakNow) break;
    total = newTotal;
  }
  return total;
}

এবং এখানে reducerঅ্যারে methodপরিবর্তিত স্ক্রিপ্ট হিসাবে রয়েছে:

Array.prototype.reducer = function(callback,initial){
  var hasInitial = arguments.length >= 2;
  var total = hasInitial ? initial : this[0];
  var breakNow = false;
  for (var i = hasInitial ? 0 : 1; i < this.length; i++) {
    var currentValue = this[i];
    var currentIndex = i;
    var newTotal = callback(total, currentValue, currentIndex, this, () => breakNow = true);
    if (breakNow) break;
    total = newTotal;
  }
  return total;
};

var list = ["w","o","r","l","d"," ","p","i","e","r","o","g","i"];

var result = list.reducer((total,current,index,arr,stop)=>{
  if(current === " ") stop(); //when called, the loop breaks
  return total + current;
},'hello ');


console.log(result);

0

বিরতির সাথে কার্যকরী সংস্করণ হ্রাস করুন 'রূপান্তর' হিসাবে প্রয়োগ করা যেতে পারে, প্রাক্তন। আন্ডারস্কোর এ।

এটি বন্ধ করার জন্য আমি একটি কনফিগার পতাকা দিয়ে এটি বাস্তবায়নের চেষ্টা করেছি যাতে বাস্তবায়ন হ্রাস করার ফলে আপনি বর্তমানে যে ডেটা কাঠামোটি ব্যবহার করছেন তা পরিবর্তন করতে হবে না।

const transform = (arr, reduce, init, config = {}) => {
  const result = arr.reduce((acc, item, i, arr) => {
    if (acc.found) return acc

    acc.value = reduce(config, acc.value, item, i, arr)

    if (config.stop) {
      acc.found = true
    }

    return acc
  }, { value: init, found: false })

  return result.value
}

module.exports = transform

ব্যবহার 1, সহজ

const a = [0, 1, 1, 3, 1]

console.log(transform(a, (config, acc, v) => {
  if (v === 3) { config.stop = true }
  if (v === 1) return ++acc
  return acc
}, 0))

ব্যবহার 2, অভ্যন্তরীণ ভেরিয়েবল হিসাবে কনফিগার ব্যবহার করুন

const pixes = Array(size).fill(0)
const pixProcessed = pixes.map((_, pixId) => {
  return transform(pics, (config, _, pic) => {
    if (pic[pixId] !== '2') config.stop = true 
    return pic[pixId]
  }, '0')
})

ব্যবহার 3, বাহ্যিক ভেরিয়েবল হিসাবে ক্যাপচার কনফিগারেশন

const thrusts2 = permute([9, 8, 7, 6, 5]).map(signals => {
  const datas = new Array(5).fill(_data())
  const ps = new Array(5).fill(0)

  let thrust = 0, config
  do {

    config = {}
    thrust = transform(signals, (_config, acc, signal, i) => {
      const res = intcode(
        datas[i], signal,
        { once: true, i: ps[i], prev: acc }
      )

      if (res) {
        [ps[i], acc] = res 
      } else {
        _config.stop = true
      }

      return acc
    }, thrust, config)

  } while (!config.stop)

  return thrust
}, 0)

0

আপনি কোনও reduceপদ্ধতির অভ্যন্তর থেকে ভাঙতে পারবেন না । আপনি কী অর্জন করতে চাইছেন তার উপর নির্ভর করে আপনি চূড়ান্ত ফলাফলকে বদলে ফেলতে পারেন (যা আপনি এটি করতে চান এমন একটি কারণ)

const result = [1, 1, 1].reduce((a, b) => a + b, 0); // returns 3

console.log(result);

const result = [1, 1, 1].reduce((a, b, c, d) => {
  if (c === 1 && b < 3) {
    return a + b + 1;
  } 
  return a + b;
}, 0); // now returns 4

console.log(result);

মনে রাখবেন: আপনি সরাসরি অ্যারে প্যারামিটারটি পুনরায় নিয়োগ করতে পারবেন না

const result = [1, 1, 1].reduce( (a, b, c, d) => {
  if (c === 0) {
    d = [1, 1, 2];
  } 
  return a + b;
}, 0); // still returns 3

console.log(result);

তবে (নীচের দিকে নির্দেশিত হিসাবে), আপনি অ্যারের সামগ্রী পরিবর্তন করে ফলাফলকে প্রভাবিত করতে পারেন:

const result = [1, 1, 1].reduce( (a, b, c, d) => {
  if (c === 0) {
    d[2] = 100;
  } 
  return a + b;
}, 0); // now returns 102

console.log(result);


4
" আপনি আর্গুমেন্টের মানগুলিকে সরাসরি এমনভাবে পরিবর্তন করতে পারবেন না যা পরবর্তী গণনাগুলিকে প্রভাবিত করে ", এটি সত্য নয়। ইসিএমএ -২ says২ বলেছেন: অ্যারের বিদ্যমান উপাদানগুলিকে যদি পরিবর্তন করা হয়, কলব্যাকফনে পাস করা হিসাবে তাদের মান সেই সময়ে তাদের ভিজিট হ্রাস করার মান হবে । আপনাদের উদাহরণ কারণ আপনার জন্য একটি নতুন মান বরাদ্দ করছি কাজ করে না , মূল অ্যারের পরিবর্তন নয়। প্রতিস্থাপন d = [1, 1, 2]সঙ্গে d[2] = 6এবং দেখুন সেখানে কি ঘটছে। ;-)
রবজি

-1

আর একটি সাধারণ বাস্তবায়ন যা আমি একই সমস্যার সমাধান নিয়ে এসেছি:

function reduce(array, reducer, first) {
  let result = first || array.shift()

  while (array.length > 0) {
    result = reducer(result, array.shift())
    if (result && result.reduced) {
      return result.reduced
    }
  }

  return result
}

-1

যদি আপনি নীচের প্যাটার্নটি ব্যবহার করে কমানোর সাথে ধারাবাহিকভাবে প্রতিশ্রুতিগুলি চেইন করতে চান:

return [1,2,3,4].reduce(function(promise,n,i,arr){
   return promise.then(function(){
       // this code is executed when the reduce loop is terminated,
       // so truncating arr here or in the call below does not works
       return somethingReturningAPromise(n);
   });
}, Promise.resolve());

তবে প্রতিশ্রুতি জিনিসগুলির ভিতরে বা বাইরে ঘটে যাওয়া কিছু অনুযায়ী কিছুটা ভাঙা দরকার, কারণ প্রথম প্রতিশ্রুতি কার্যকর হওয়ার আগে হ্রাস লুপটি বন্ধ হয়ে যায়, প্রতিশ্রুতি কলব্যাকগুলিতে অ্যারে ছাঁটাই করে আমি এই বাস্তবায়নটি শেষ করেছি:

function reduce(array, promise, fn, i) {
  i=i||0;
  return promise
  .then(function(){
    return fn(promise,array[i]);
  })
  .then(function(result){
    if (!promise.break && ++i<array.length) {
      return reduce(array,promise,fn,i);
    } else {
      return result;
    }
  })
}

তারপরে আপনি এর মতো কিছু করতে পারেন:

var promise=Promise.resolve();
reduce([1,2,3,4],promise,function(promise,val){
  return iter(promise, val);
}).catch(console.error);

function iter(promise, val) {
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      if (promise.break) return reject('break');
      console.log(val);
      if (val==3) {promise.break=true;}
      resolve(val);
    }, 4000-1000*val);
  });
}

-1

আমি এটি নীচের মতো সমাধান করেছি, উদাহরণস্বরূপ সেই someপদ্ধতিতে যেখানে শর্ট সার্কিট অনেকগুলি সঞ্চয় করতে পারে:

const someShort = (list, fn) => {
  let t;
  try {
    return list.reduce((acc, el) => {
      t = fn(el);
      console.log('found ?', el, t)
      if (t) {
        throw ''
      }
      return t
    }, false)
  } catch (e) {
    return t
  }
}

const someEven = someShort([1, 2, 3, 1, 5], el => el % 2 === 0)

console.log(someEven)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.