একটি পুনরুক্তিতে মানচিত্র () ব্যবহার করা


92

বলুন আমাদের কাছে একটি মানচিত্র রয়েছে:, মানচিত্রের পুনরুদ্ধারকারীকে let m = new Map();ব্যবহার করে m.values()

তবে আমি ব্যবহার করতে পারি না forEach()বা map()সেই পুনরুক্তি করতে এবং ES6 এর মতো অফার ফাংশনগুলির মতো এই পুনরুক্তিকারীটির উপর কিছুক্ষণের লুপটি একটি অ্যান্টি-প্যাটার্নের মতো মনে হয় map()

সুতরাং map()একটি পুনরাবৃত্তি ব্যবহার করার উপায় আছে ?


বাক্সের বাইরে নয়, তবে আপনি তৃতীয় পক্ষের লাইব্রেরি lodash mapফাংশনের মতো ব্যবহার করতে পারেন যা মানচিত্রকে সমর্থন করে।
বিপজ্জনক

মানচিত্রের নিজস্ব -মান জোড়ায় পুনরাবৃত্তি করার জন্য নিজেই একটি ফরচ প্রতিটি রয়েছে ।
বিপজ্জনক

পুনরাবৃত্তিকে একটি অ্যারে রূপান্তরিত করা এবং এটির মতো মানচিত্রের মতো Array.from(m.values()).map(...)কাজ করা, তবে আমি মনে করি এটি করার সর্বোত্তম উপায় নয়।
জিমিনপি

আপনার মতো কোন সমস্যাটি পুনরুক্তি ব্যবহার করে সমাধান করা উচিত যখন একটি অ্যারে ব্যবহারের জন্য আরও ভাল ফিট করে Array#map?
নিনা স্কলজ

4
@NinaScholz আমি এখানে মত একটি সাধারণ সেট ব্যবহার করছি: stackoverflow.com/a/29783624/4279201
shinzou

উত্তর:


84

এটি করার সহজতম এবং সর্বনিম্ন পারফরম্যান্ট উপায় হ'ল:

Array.from(m).map(([key,value]) => /* whatever */)

এখনো ভাল

Array.from(m, ([key, value]) => /* whatever */))

Array.fromযেকোন পুনরাবৃত্ত বা অ্যারে-জাতীয় জিনিস লাগে এবং এটিকে অ্যারে রূপান্তর করে! ড্যানিয়েল মন্তব্যগুলিতে যেমন উল্লেখ করেছেন, আমরা কোনও পুনরাবৃত্তি এবং পরবর্তীকালে একটি মধ্যবর্তী অ্যারে সরানোর জন্য রূপান্তরটিতে একটি ম্যাপিং ফাংশন যুক্ত করতে পারি।

ব্যবহার Array.fromথেকে আপনার কর্মক্ষমতা সরানো হবে O(1)থেকে O(n)মন্তব্য আউট @hraban পয়েন্ট হিসাবে। যেহেতু mএকটি Map, এবং এগুলি অসীম হতে পারে না, তাই আমাদের অসীম অনুক্রম সম্পর্কে চিন্তা করতে হবে না। বেশিরভাগ উদাহরণের জন্য, এটি যথেষ্ট।

মানচিত্রের মাধ্যমে লুপ করার আরও কয়েকটি উপায় রয়েছে।

ব্যবহার forEach

m.forEach((value,key) => /* stuff */ )

ব্যবহার for..of

var myMap = new Map();
myMap.set(0, 'zero');
myMap.set(1, 'one');
for (var [key, value] of myMap) {
  console.log(key + ' = ' + value);
}
// 0 = zero
// 1 = one

মানচিত্রের কি অসীম দৈর্ঘ্য থাকতে পারে?
ktilcu

4
একটি পুনরুক্তিকারীর জন্য @ কেটিলকু: হ্যাঁ। একটি পুনরুত্পাদনকারী উপর একটি। ম্যাপ জেনারেটরের একটি রূপান্তর হিসাবে ভাবা যেতে পারে, যা নিজেই একটি পুনরুক্তি ফেরত। একটি উপাদান পপিং অন্তর্নিহিত পুনরুদ্ধারকারী কল, উপাদান রূপান্তর, এবং যে ফিরে।
হারাবান

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

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

4
@ কটিলকু আপনি পরিবর্তে কল করতে পারেন Array.from(m, ([key,value]) => /* whatever */)(ম্যাপিং ফাংশনটি এর অভ্যন্তরে রয়েছে তা লক্ষ্য করুন from) এবং তারপরে কোনও মধ্যবর্তী অ্যারে তৈরি করা হয়নি ( উত্স )। এটি এখনও ও (1) থেকে ও (এন) এ চলে যায়, তবে কমপক্ষে পুনরাবৃত্তি এবং ম্যাপিং কেবল একটি পূর্ণ পুনরাবৃত্তির মধ্যে ঘটে।
ড্যানিয়েল

19

আপনি এটিকে লুপ করতে অন্য পুনরাবৃত্তির ক্রিয়াটি সংজ্ঞায়িত করতে পারেন:

function* generator() {
    for (let i = 0; i < 10; i++) {
        console.log(i);
        yield i;
    }
}

function* mapIterator(iterator, mapping) {
    for (let i of iterator) {
        yield mapping(i);
    }
}

let values = generator();
let mapped = mapIterator(values, (i) => {
    let result = i*2;
    console.log(`x2 = ${result}`);
    return result;
});

console.log('The values will be generated right now.');
console.log(Array.from(mapped).join(','));

এখন আপনি জিজ্ঞাসা করতে পারেন: কেবল Array.fromপরিবর্তে ব্যবহার করবেন না কেন ? কারণ এই সমগ্র পুনরুক্তিকারীর মাধ্যমে চালানো হবে, এটি একটি (অস্থায়ী) অ্যারেতে বারবার এটা আবার সংরক্ষণ করুন এবং তারপর ম্যাপিং না। তালিকাটি বিশাল (বা এমনকি সম্ভাব্য অসীম) হলে এটি অপ্রয়োজনীয় মেমরির ব্যবহারের দিকে পরিচালিত করবে।

অবশ্যই, যদি আইটেমের তালিকা মোটামুটি ছোট হয় তবে ব্যবহারের জন্য Array.fromপর্যাপ্ত পরিমাণের বেশি হওয়া উচিত।


সীমাবদ্ধ পরিমাণের মেমরি কীভাবে অসীম ডেটা স্ট্রাকচার ধরে রাখতে পারে?
shinzou

4
এটা না, যে পয়েন্ট। এটি ব্যবহার করে আপনি পুনরাবৃত্তির উত্স পরিবর্তনের জন্য এবং শেষ পর্যন্ত একটি গ্রাহক ডুবির কাছে একটি পুনরুক্তি উত্সকে শৃঙ্খলাবদ্ধ করে "ডেটা স্ট্রিম" তৈরি করতে পারেন। উদাহরণস্বরূপ অডিও প্রসেসিং স্ট্রিমিং, বিশাল ফাইল নিয়ে কাজ করা, ডেটাবেসগুলিতে অ্যাগ্রিগেটর ইত্যাদি ইত্যাদি
hraban

4
আমি এই উত্তর পছন্দ। কেউ কি এমন লাইব্রেরি সুপারিশ করতে পারে যা পুনরাবৃত্তিতে অ্যারের মতো পদ্ধতিগুলি সরবরাহ করে?
জোয়েল ম্যালোন

4
mapIterator()গ্যারান্টি দেয় না যে অন্তর্নিহিত আয়রেটরটি যথাযথভাবে বন্ধ হয়ে যাবে ( iterator.return()ডাকা হবে) যদি না ফেরতের মানটির পরেরটির কমপক্ষে একবার কল না করা হয়। দেখুন: repeater.js.org/docs/safety
Jaka Jančar

আপনি কেন কেবল একটির পরিবর্তে ম্যানুয়ালি পুনরায় প্রোটোকল ব্যবহার করছেন for .. of .. loop?
কৌলিকস

11

এটি Array.fromঅর্জনের জন্য দ্বিতীয় যুক্তিটি ব্যবহার করা সবচেয়ে সহজ এবং সর্বাধিক পারফরম্যান্ট উপায় :

const map = new Map()
map.set('a', 1)
map.set('b', 2)

Array.from(map, ([key, value]) => `${key}:${value}`)
// ['a:1', 'b:2']

এই পদ্ধতির কোনও অসীম পুনরাবৃত্তিযোগ্য জন্য কাজ করে । এবং এটি পৃথক কল ব্যবহার করা এড়িয়ে চলে Array.from(map).map(...)যা পুনরাবৃত্তিযোগ্য দ্বিগুণ হয়ে পুনরায় সম্পাদন করবে এবং কার্য সম্পাদনের জন্য আরও খারাপ হবে।


3

আপনি পুনরাবৃত্তিযোগ্য উপর একটি পুনরুদ্ধার পুনরুদ্ধার করতে পারে, এবং আবার পুনরাবৃত্তি করতে হবে যে প্রতিটি পুনরাবৃত্তি উপাদান ম্যাপিং কলব্যাক ফাংশন কল।

const map = (iterable, callback) => {
  return {
    [Symbol.iterator]() {
      const iterator = iterable[Symbol.iterator]();
      return {
        next() {
          const r = iterator.next();
          if (r.done)
            return r;
          else {
            return {
              value: callback(r.value),
              done: false,
            };
          }
        }
      }
    }
  }
};

// Arrays are iterable
console.log(...map([0, 1, 2, 3, 4], (num) => 2 * num)); // 0 2 4 6 8

2

আপনি পুনরাবৃত্তদের জন্য অ্যারি -জাতীয় পদ্ধতি প্রয়োগ করে এমন ইটিরিরি ব্যবহার করতে পারেন :

import { query } from 'itiriri';

let m = new Map();
// set map ...

query(m).filter([k, v] => k < 10).forEach([k, v] => console.log(v));
let arr = query(m.values()).map(v => v * 10).toArray();

সুন্দর! জেএসের এপিআইগুলি এইভাবে করা উচিত ছিল। সর্বদা হিসাবে, মরিচ
উড়ন্ত মেষ

"সর্বদা হিসাবে, মরিচা এটি সঠিকভাবে পেয়েছে" নিশ্চিত ... পুনরুক্তি ইন্টারফেস github.com/tc39/proposal-iterator-helpers এর জন্য সমস্ত ধরণের সহায়ক ফাংশনগুলির জন্য একটি মানীকরণের প্রস্তাব রয়েছে আপনি আজ এটিকে এফএনএস fromথেকে আমদানি করে কোরজ সহ ব্যবহার করতে পারেন "কোর-জেএস-বিশুদ্ধ / বৈশিষ্ট্য / পুনরাবৃত্তি" যা "নতুন" পুনরাবৃত্তিকে প্রদান করে।
chpio

2

Https://www.npmjs.com/package/fluent-iterable এ একবার দেখুন

পুনরাবৃত্ত সমস্ত (মানচিত্র, জেনারেটর ফাংশন, অ্যারে) এবং অ্যাসিঙ্ক পুনরাবৃত্তগুলির সাথে কাজ করে।

const map = new Map();
...
console.log(fluent(map).filter(..).map(..));

1

একটি প্রস্তাব রয়েছে, এটি একাধিক সহায়ক ফাংশন এনেছে Iterator: https://github.com/tc39/proposal-iterator-helpers ( রেন্ডার )

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

import { from as iterFrom } from "core-js-pure/features/iterator";

// or if it's working for you:
// import iterFrom from "core-js-pure/features/iterator/from";

let m = new Map();

m.set("13", 37);
m.set("42", 42);

const arr = iterFrom(m.values())
  .map((val) => val * 2)
  .toArray();

// prints "[74, 84]"
console.log(arr);

0

অন্যান্য উত্তরগুলি এখানে ... অদ্ভুত। তারা মনে হয় পুনরাবৃত্তি প্রোটোকলের অংশগুলি পুনরায় প্রয়োগ করছে। আপনি কেবল এটি করতে পারেন:

function* mapIter(iterable, callback) {
  for (let x of iterable) {
    yield callback(x);
  }
}

এবং যদি আপনি কোনও কংক্রিট ফলাফল চান তবে কেবল স্প্রেড অপারেটরটি ব্যবহার করুন ...

[...iterMap([1, 2, 3], x => x**2)]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.