আমাদের ফ্ল্যাটম্যাপ ব্যবহার করা দরকার কেন?


94

আমি আরএক্সজেএস ব্যবহার শুরু করছি এবং আমি বুঝতে পারি না কেন এই উদাহরণে আমাদের মতো ফাংশন ব্যবহার করা প্রয়োজন flatMapবা concatAll; এখানে অ্যারের অ্যারে কোথায়?

var requestStream = Rx.Observable.just('https://api.github.com/users');

var responseMetastream = requestStream
  .flatMap(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

responseMetastream.subscribe(url => {console.log(url)})

যদি কেউ দৃশ্যমানভাবে যা ঘটছে তা ব্যাখ্যা করতে পারে, তবে এটি খুব সহায়ক হবে।


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

4
আমি মনে করি যদি flatMapনামকরণ mapThenFlattenকরা হত, তবে এটি কম বিভ্রান্তিকর হবে।
ছাগল

উত্তর:


73

আমি যখন একবার নজর দিতে শুরু করি তখন আমি Rxjsসেই পাথরেও হোঁচট খেয়েছি। আমাকে কী সাহায্য করেছিল তা নিম্নলিখিত:

  • প্রতিক্রিয়া উদাহরণস্বরূপ, এর জন্য flatMap: http://reactivex.io/docamentation/operators/flatmap.html
  • rxmarbles থেকে ডকুমেন্টেশন: http://rxmarbles.com/ । আপনি flatMapসেখানে পাবেন না, আপনি অবশ্যই mergeMapপরিবর্তে (অন্য নাম) তাকান।
  • আরএক্সের পরিচিতি যা আপনি মিস করছেন: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754 । এটি একটি খুব অনুরূপ উদাহরণ সম্বোধন করে। বিশেষত এটি এই সত্যটিকে সম্বোধন করে যে একটি প্রতিশ্রুতি একটি পর্যবেক্ষণযোগ্য মাত্র একটি মূল্য নির্ধারণের অনুরূপ।
  • অবশেষে আরএক্সজাভা থেকে টাইপ তথ্য তাকান। জাভাস্ক্রিপ্ট টাইপ করা হচ্ছে না এখানে সাহায্য করে না। মূলত যদি Observable<T>কোন পর্যবেক্ষণযোগ্য অবজেক্টকে চিহ্নিত করে যা টি টাইপের মানকে ধাক্কা দেয়, তবে তার আর্গুমেন্ট হিসাবে flatMapটাইপের একটি কার্য গ্রহণ করে T' -> Observable<T>এবং প্রত্যাবর্তন করে Observable<T>mapটাইপ T' -> Tএবং রিটার্ন একটি ফাংশন লাগে Observable<T>

    আপনার উদাহরণে ফিরে যেতে, আপনার একটি ফাংশন রয়েছে যা ইউআরএল স্ট্রিং থেকে প্রতিশ্রুতি দেয়। সুতরাং T' : string, এবং T : promise। এবং কি থেকে আমরা আগে বলেন promise : Observable<T''>তাই হয়, T : Observable<T''>সঙ্গে T'' : html। আপনি ফাংশন উত্পাদক যে প্রতিশ্রুতি করা map, আপনি পেতে Observable<Observable<T''>>কি আপনি চান যখন Observable<T''>: আপনি পর্যবেক্ষণযোগ্য নির্গত করতে চান htmlমান। flatMapএটিকে বলা হয় কারণ ফলাফলটি সমতল হয় (একটি পর্যবেক্ষণযোগ্য স্তর সরিয়ে দেয়) এর ফলাফল থেকে map। আপনার ব্যাকগ্রাউন্ডের উপর নির্ভর করে এটি আপনার কাছে চীনা হতে পারে তবে টাইপিংয়ের তথ্য এবং এখান থেকে আঁকার সাথে আমার কাছে সমস্ত কিছুই স্ফটিক স্পষ্ট হয়ে উঠেছে: http://reactivex.io/docamentation/operators/flatmap.html


4
আমি উল্লেখ করতে ভুলে গেছি যে আপনি সরল করতে সক্ষম return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));হবেন return jQuery.getJSON(requestUrl);যেমন flatMapএকটি নির্বাচক ফাংশনও গ্রহণ করে যা প্রতিশ্রুতি দেয় যেমন টাইপের ফাংশন T' -> Promise
ব্যবহারকারী3743222

4
বাহ, যে গিটহাব গিস্ট ( gist.github.com/staltz/868e7e9bc2a7b8c1f754 ) রক্তাক্ত চমত্কার। আমি RxJS এর ​​মতো যে কোনও রিঅ্যাকটিভএক্স লাইব্রেরির সাথে কাজ করা প্রত্যেককেই এটির প্রস্তাব দিচ্ছি।
জ্যাকব স্ট্যাম্ম

@ জ্যাকবস্ট্যাম আমি সম্মত কেবল জিনিসগুলি সহজ করে তোলে।
নিষ্ঠুর এঙ্গাইন

কি এই সিনট্যাক্স মানে: T’ -> T? আমি Tজেনেরিক হিসাবে বুঝতে পারি , তবে এস্ট্রোফের এবং চর্বিযুক্ত তীরটি কী?
1252748

আপনি উত্তরের কোথাও অর্থ পরিবর্তন না করেই X বা Y দ্বারা টি প্রতিস্থাপন করতে পারেন। টাইপ স্বাক্ষরের জন্য তীরটি হ্যাসেল নোটেশন। সুতরাং টি '-> টি হ'ল একটি ফাংশনের জন্য স্বাক্ষর যা টাইপ টি এর একটি উপাদান নেয় এবং টি টাইপের একটি উপাদান ফেরত দেয়
user3743222

124
['a','b','c'].flatMap(function(e) {
    return [e, e+ 'x', e+ 'y',  e+ 'z'  ];
});
//['a', 'ax', 'ay', 'az', 'b', 'bx', 'by', 'bz', 'c', 'cx', 'cy', 'cz']


['a','b','c'].map(function(e) {
    return [e, e+ 'x', e+ 'y',  e+ 'z'  ];
});
//[Array[4], Array[4], Array[4]]

আপনি যখন পর্যবেক্ষণযোগ্য যার ফলাফল বেশি পর্যবেক্ষণযোগ্য থাকে আপনি ফ্ল্যাটম্যাপ ব্যবহার করেন।

আপনার যদি পর্যবেক্ষণযোগ্য থাকে যা অন্য কোনও পর্যবেক্ষণযোগ্য দ্বারা উত্পাদিত হয় তবে আপনি এটি সরাসরি ফিল্টার, হ্রাস বা ম্যাপ করতে পারবেন না কারণ আপনার কাছে পর্যবেক্ষণযোগ্য ডেটা নেই। যদি আপনি পর্যবেক্ষণযোগ্য উত্পাদন করেন তবে মানচিত্রের উপরে ফ্ল্যাটম্যাপ বেছে নিন; তাহলে আপনি ঠিক আছেন।

দ্বিতীয় স্নিপেটের মতো, আপনি যদি অ্যাসিঙ্ক অপারেশন করছেন তবে আপনার ফ্ল্যাটম্যাপ ব্যবহার করা দরকার।

var source = Rx.Observable.interval(100).take(10).map(function(num){
    return num+1
});
source.subscribe(function(e){
    console.log(e)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>

var source = Rx.Observable.interval(100).take(10).flatMap(function(num){
    return Rx.Observable.timer(100).map(() => num)
});
source.subscribe(function(e){
    console.log(e)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>


34

লোকেরা সংজ্ঞা দিয়ে যে বিষয়গুলিকে জটিল করে তুলবে তা বলে:

ফ্ল্যাটম্যাপ পর্যবেক্ষণযোগ্য দ্বারা নির্গত আইটেমগুলি পর্যবেক্ষণযোগ্যগুলিতে রূপান্তরিত করে, তারপরে সেগুলি থেকে নির্গমনকে একক পর্যবেক্ষণযোগ্য করে তুলুন

আমি শপথ করছি এই সংজ্ঞাটি এখনও আমাকে বিভ্রান্ত করে তবে আমি এটি সহজ পদ্ধতিতে ব্যাখ্যা করতে যাচ্ছি যা একটি উদাহরণ ব্যবহার করে

আমাদের পরিস্থিতি : আমাদের একটি পর্যবেক্ষণযোগ্য রয়েছে যা ডেটা (সাধারণ ইউআরএল) ফেরত দেয় যা আমরা এইচটিটিপি কল করতে ব্যবহার করতে যা যা আমাদের প্রয়োজনীয় ডেটা সম্বলিত পর্যবেক্ষণযোগ্যকে ফিরিয়ে দেবে যাতে আপনি পরিস্থিতিটি এইরকম দেখতে পারেন:

Observable 1
    |_
       Make Http Call Using Observable 1 Data (returns Observable_2)
            |_
               The Data We Need

যাতে আপনি দেখতে পাচ্ছেন যে আমরা আমাদের প্রয়োজনীয় ডেটাতে পৌঁছাতে পারি না তাই ডাটা পুনরুদ্ধার করার প্রথম উপায়টি আমরা কেবলমাত্র সাধারণ সাবস্ক্রিপশনগুলি এর মতো ব্যবহার করতে পারি:

Observable_1.subscribe((URL) => {
         Http.get(URL).subscribe((Data_We_Need) => {
                  console.log(Data_We_Need);
          });
});

এটি কাজ করে তবে আপনি দেখতে পাচ্ছেন আমাদের ডেটা পেতে আমাদের সাবস্ক্রিপশন করতে হবে এটি বর্তমানে খারাপ দেখাচ্ছে না তবে কল্পনা করুন যে আমাদের 10 টি নেস্টেড সাবস্ক্রিপশন রয়েছে যা অকল্পনীয় হয়ে উঠবে।

সুতরাং এটি পরিচালনা করার একটি সর্বোত্তম উপায় হ'ল অপারেটরটি ব্যবহার করা flatMapযা একই কাজ করবে তবে আমাদের সেই নেস্টেড সাবস্ক্রিপশন এড়াতে সক্ষম করে:

Observable_1
    .flatMap(URL => Http.get(URL))
    .subscribe(Data_We_Need => console.log(Data_We_Need));

32

flatMap একটি পর্যবেক্ষণযোগ্য দ্বারা নির্গত আইটেমগুলিকে নতুন পর্যবেক্ষণযোগ্যগুলিতে রূপান্তর করুন, তারপরে সেগুলি থেকে নির্গমনকে একক পর্যবেক্ষণযোগ্যতে প্রসারিত করুন।

নীচের get("posts")দৃশ্যটি দেখুন যেখানে "পর্যবেক্ষণ" দ্বারা পর্যবেক্ষণযোগ্য একটি পর্যবেক্ষণ ফিরিয়ে আনে flatMap

myObservable.map(e => get("posts")).subscribe(o => console.log(o));
// this would log Observable objects to console.  

myObservable.flatMap(e => get("posts")).subscribe(o => console.log(o));
// this would log posts to console.

4
সুন্দর, সহজ উত্তর। আমি মনে করি এটি সেরা হতে পারে।
ভন

"ফ্ল্যাটম্যাপ কোনও পর্যবেক্ষণযোগ্য দ্বারা নির্গত আইটেমগুলিকে নতুন পর্যবেক্ষণযোগ্যগুলিতে রূপান্তরিত করে, তারপরে সেগুলি থেকে নির্গমনকে একক পর্যবেক্ষণযোগ্যতে রূপান্তরিত করে" " এটি দুর্দান্ত জিনিস।
এমবিাক


16

এটি অ্যারের অ্যারে নয়। এটি পর্যবেক্ষণযোগ্য (গুলি) এর একটি পর্যবেক্ষণযোগ্য।

নিম্নলিখিত স্ট্রিং একটি পর্যবেক্ষণযোগ্য স্ট্রিম প্রদান করে।

requestStream
  .map(function(requestUrl) {
    return requestUrl;
  });

যদিও এটি জসনের পর্যবেক্ষণযোগ্য প্রবাহের একটি পর্যবেক্ষণযোগ্য স্ট্রিমটি দেয়

requestStream
  .map(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

flatMap আমাদের জন্য পর্যবেক্ষণযোগ্যটিকে স্বয়ংক্রিয়ভাবে ফ্ল্যাট করে তোলে যাতে আমরা সরাসরি জসন স্ট্রিমটি পর্যবেক্ষণ করতে পারি


4
এই ধারণাটি বোঝা মুশকিল, আপনি কী বোঝাতে পারেন "json এর পর্যবেক্ষণযোগ্য প্রবাহের একটি পর্যবেক্ষণযোগ্য স্ট্রিম" ফিরিয়ে দেয় তার অর্থ আপনি কী ভিজ্যুয়ালটিতে মন্তব্য যুক্ত করতে পারেন? ধন্যবাদ
ব্যবহারকারী 233232

@ ব্যবহারকারী 233232, [এক্স, এক্স, এক্স, এক্স] থেকে [[
এক্সএক্সএক্সএক্স

প্রথম বাক্যটি বোঝার মূল কথাটি বুঝতে হবে যে flatMap(এবং map) অ্যারেগুলির জন্য বিশেষ নয়। অ্যারে, অভিধান, "বিকল্পগুলি", প্রতিক্রিয়াশীল স্ট্রিমস, প্রতিশ্রুতিগুলি, পয়েন্টারগুলি এবং এমনকি নিজেরাই ফাংশন সহ যেকোন জেনেরিক ধারক বা মোড়কের উপর এই ক্রিয়াকলাপগুলি সংজ্ঞায়িত করা সম্ভব। এটি মোনাড নামে একটি গাণিতিক নির্মাণের উদীয়মান সম্পত্তি। উপরের সমস্ত উদাহরণ মোনাড হওয়ার প্রয়োজনীয়তাগুলি পূরণ করে এবং তাই সেগুলি সমস্তর একটি সংজ্ঞা দেওয়া যেতে পারে mapএবং একটি flatMap(কিছু সতর্কতা সহ)।
mklbtz

14

সাবস্ক্রাইব ব্যবহার করে ফ্ল্যাটম্যাপের সমতুল্য বাস্তবায়ন দেখানোর জন্য এখানে।

ফ্ল্যাটম্যাপ ছাড়াই:

this.searchField.valueChanges.debounceTime(400)
.subscribe(
  term => this.searchService.search(term)
  .subscribe( results => {
      console.log(results);  
      this.result = results;
    }
  );
);

ফ্ল্যাটম্যাপ সহ:

this.searchField.valueChanges.debounceTime(400)
    .flatMap(term => this.searchService.search(term))
    .subscribe(results => {
      console.log(results);
      this.result = results;
    });

http://plnkr.co/edit/BHGmEcdS5eQGX703eRRE?p= পূর্বরূপ

আশা করি এটি সাহায্য করতে পারে।

অলিভিয়ার


13

একটি পর্যবেক্ষণযোগ্য এমন একটি বস্তু যা ইভেন্টগুলির একটি স্ট্রিমকে নির্গত করে: পরবর্তী, ত্রুটি এবং সম্পূর্ণ।

যখন আপনার ফাংশন কোনও পর্যবেক্ষণযোগ্য ফেরত দেয়, এটি কোনও স্ট্রিম ফিরিয়ে দেয় না, তবে পর্যবেক্ষণের উদাহরণ। flatMapঅপারেটর কেবল একটি প্রবাহ যে দৃষ্টান্ত মানচিত্র তৈরী করে।

এটির flatMapসাথে তুলনা করার সময় এর আচরণ map: প্রদত্ত ফাংশনটি কার্যকর করুন এবং ফলস্বরূপ বস্তুকে একটি স্ট্রিমে সমতল করুন।


7

ফ্ল্যাটম্যাপ সহ

var requestStream = Rx.Observable.just('https://api.github.com/users');

var responseMetastream = requestStream
  .flatMap(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

responseMetastream.subscribe(json => {console.log(json)})

ফ্ল্যাটম্যাপ ছাড়াই

var requestStream = Rx.Observable.just('https://api.github.com/users');

var responseMetastream = requestStream
  .map(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

responseMetastream.subscribe(jsonStream => {
  jsonStream.subscribe(json => {console.log(json)})
})

0

ফ্ল্যাটম্যাপ পর্যবেক্ষণযোগ্য দ্বারা নির্গত আইটেমগুলি পর্যবেক্ষণযোগ্যগুলিতে রূপান্তরিত করে, তারপরে সেগুলি থেকে নির্গমনকে একক পর্যবেক্ষণযোগ্য করে তুলুন

আমি বোকা নই তবে এটি 10 ​​বার পড়তে হয়েছিল এবং এখনও এটি পেলাম না। যখন আমি কোড স্নিপেট পড়ি:

[1,2,3].map(x => [x, x * 10])
// [[1, 10], [2, 20], [3, 30]]

[1,2,3].flatMap(x => [x, x * 10])
// [1, 10, 2, 20, 3, 30]

তখন আমি বুঝতে পারছিলাম কি হচ্ছে, এটি দুটি জিনিস করে:

ফ্ল্যাটম্যাপ :

  1. মানচিত্র : রূপান্তর *) পর্যবেক্ষণযোগ্যগুলিতে নির্গত আইটেমগুলি into
  2. ফ্ল্যাট : তারপরে সেই পর্যবেক্ষণযোগ্যকে একটি পর্যবেক্ষণযোগ্য হিসাবে মার্জ করুন।

*) রূপান্তর শব্দটি বলে আইটেমটি অন্য কোনও কিছুর মধ্যে রূপান্তরিত হতে পারে।

তারপরে মার্জ অপারেটরটি পরিষ্কার হয়ে যায়, এটি ম্যাপিং ছাড়াই চাটুটি করে। কেন একে মার্জম্যাপ বলছেন না ? মনে হচ্ছে সেখানে একজন ওরফে mergeMap জন্য এই নামের flatMap

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