জাভাস্ক্রিপ্ট হাশম্যাপ সমতুল্য


353

এই উত্তরের 3 আপডেটে যেমনটি পরিষ্কার হয়েছে , এই স্বরলিপি:

var hash = {};
hash[X]

আসলে বস্তুটি হ্যাশ করে না X; এটি আসলে Xএকটি স্ট্রিংয়ে রূপান্তরিত হয় ( .toString()এটি যদি কোনও বস্তু বা বিভিন্ন আদিম ধরণের জন্য কিছু অন্তর্নির্মিত রূপান্তরগুলির মাধ্যমে হয়) এবং তারপরে হ্যাশ না করে সেই স্ট্রিংটিকে দেখায় "hash " । অবজেক্টের সাম্যতাও যাচাই করা হয় না - যদি দুটি পৃথক বস্তুর একই স্ট্রিং রূপান্তর থাকে তবে তারা কেবল একে অপরকে ওভাররাইট করে।

এটি দেওয়া - জাভাস্ক্রিপ্টে হ্যাশম্যাপগুলির কোনও কার্যকর প্রয়োগ রয়েছে? (উদাহরণস্বরূপ, ২ য় গুগলের ফলাফল javascript hashmapকোনও প্রয়োগের জন্য ফলদান দেয় যা ও (এন)। বিভিন্ন অন্যান্য ফলাফল সমতুল্য স্ট্রিং উপস্থাপনা সহ বিভিন্ন বস্তু একে অপরকে ওভাররাইট করে দেয় এ বিষয়টি এড়িয়ে যায়।


1
@ ক্লাডিউ: সম্পাদনার জন্য দুঃখিত, তবে শিরোনামের "মানচিত্র" সত্যিই বিভ্রান্তিকর ছিল। আপনি যদি একমত না হন তবে পিছনে রোল করুন, আমি পৃষ্ঠপোষকতা করার ইচ্ছা করি নি। :)
টমলাক

6
@ ক্লডিউ: আপনি জাভাস্ক্রিপ্ট সম্পর্কে অনেক প্রশ্ন জিজ্ঞাসা করেছেন। ভাল প্রশ্ন। আমি এটা পছন্দ করি।
কিছু

2
@ ক্লডিউ: এছাড়াও, আপনি যে গুগল ফলাফলটি উল্লেখ করেছেন তার সাথে লিঙ্ক করতে পারবেন? গুগলের বিভিন্ন স্থানীয় সংস্করণ বিভিন্ন ফলাফল দেয়, আপনি যে প্রয়োগটি উল্লেখ করেছেন তা আমার কাছে প্রদর্শিত হবে বলে মনে হয় না।
টমলক

@ তোমালাক: আমি ঠিক একই জিনিস লিখতে যাচ্ছিলাম!
কিছু

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

উত্তর:


368

কেন নিজের আইটেমগুলিকে ম্যানুয়ালি হ্যাশ করবেন না, এবং নিয়মিত জাভাস্ক্রিপ্ট অভিধানের কী হিসাবে ফলাফলের স্ট্রিংগুলি ব্যবহার করবেন না? সর্বোপরি আপনি নিজের অবস্থানকে কী অনন্য করে তোলে তা জানতে সর্বোত্তম অবস্থানে রয়েছেন। এটা যা আমি করি.

উদাহরণ:

var key = function(obj){
  // some unique object-dependent key
  return obj.totallyUniqueEmployeeIdKey; // just an example
};

var dict = {};

dict[key(obj1)] = obj1;
dict[key(obj2)] = obj2;

এইভাবে আপনি জাভাস্ক্রিপ্ট দ্বারা মেমরি বরাদ্দ ভারী উত্তোলন এবং ওভারফ্লো হ্যান্ডলিং ব্যতীত জাভাস্ক্রিপ্ট দ্বারা সম্পন্ন সূচকগুলি নিয়ন্ত্রণ করতে পারেন।

অবশ্যই, যদি আপনি সত্যিই "শিল্প-গ্রেড সমাধান" চান তবে আপনি মূল ফাংশন এবং পাত্রে সমস্ত প্রয়োজনীয় এপিআই দিয়ে একটি প্যারামিটারাইজড ক্লাস তৈরি করতে পারেন, তবে ... আমরা জাভাস্ক্রিপ্ট ব্যবহার করি এবং সহজ এবং হালকা ওজন হওয়ার চেষ্টা করি, তাই এই কার্যকরী সমাধানটি সহজ এবং দ্রুত।

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

২০১৪-এ আপডেট করুন: ২০০৮ সালে জবাব দেওয়া হয়েছে এই সাধারণ সমাধানটির আরও বিশদ ব্যাখ্যা দরকার। আমাকে প্রশ্নোত্তর আকারে ধারণাটি পরিষ্কার করতে দিন।

আপনার সমাধানটিতে একটি আসল হ্যাশ নেই। এটা কোথায় ???

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

আপনি কীভাবে জানবেন যে তারা হ্যাশ ব্যবহার করে?

কোনও কী দ্বারা সম্বোধনযোগ্য অবজেক্টের সংগ্রহকে রাখার জন্য তিনটি প্রধান উপায় রয়েছে:

  • ক্রমবিন্যাসহীন। এক্ষেত্রে কোনও কীটিকে তার কী দ্বারা পুনরুদ্ধার করতে আমাদের যখন খুঁজে পাওয়া যায় তখন সমস্ত কী থামানো উচিত। গড়ে এটি n / 2 তুলনা নিতে হবে।
  • অর্ডার দেওয়া হয়েছে।
    • উদাহরণ # 1: একটি বাছাই করা অ্যারে - বাইনারি অনুসন্ধান করে আমরা গড়ে key লগ 2 (এন) তুলনা করার পরে আমাদের কীটি পাই। অনেক ভাল.
    • উদাহরণ # 2: একটি গাছ। আবার এটি ~ লগ (এন) এর প্রচেষ্টা হবে।
  • হ্যাশ টেবিল. গড়ে এটির জন্য একটি ধ্রুবক সময় প্রয়োজন। তুলনা করুন: ও (এন) বনাম ও (লগ এন) বনাম ও (1)। গম্ভীর গর্জন।

স্পষ্টতই জাভাস্ক্রিপ্ট অবজেক্টগুলি সাধারণ কেসগুলি হ্যান্ডেল করতে কোনও ফর্মে হ্যাশ টেবিল ব্যবহার করে।

ব্রাউজার বিক্রেতারা কি আসলেই হ্যাশ টেবিল ব্যবহার করেন ???

সত্যিই।

তারা সংঘর্ষ পরিচালনা করে?

হ্যাঁ. উপরে দেখুন. যদি আপনি অসম স্ট্রিংগুলিতে সংঘর্ষের মুখোমুখি হন তবে দয়া করে কোনও বিক্রেতার সাথে বাগ ফাইল করতে দ্বিধা করবেন না।

তাহলে আপনার ধারণাটি কী?

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

জাভাস্ক্রিপ্ট সহ এই কীটি ব্যবহার করুন Objectডিফল্ট বৈশিষ্ট্যগুলির সাথে সম্ভাব্য সংঘর্ষগুলি পরিষ্কার করার সময় এর অন্তর্নির্মিত হ্যাশ টেবিলটি উত্তোলনের জন্য ।

আপনাকে শুরু করার উদাহরণগুলি:

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

আমি আপনার পরামর্শ ব্যবহার করেছি এবং ব্যবহারকারীর নাম ব্যবহার করে সমস্ত বস্তুকে ক্যাশে করেছি। তবে কিছু জ্ঞানী লোকটির নাম দেওয়া হয়েছে "টু স্ট্রিং", যা বিল্ট-ইন সম্পত্তি! আমার এখন কি করা উচিত?

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

সাধারণভাবে এটি সেই জায়গা, যেখানে আমাদের সৃজনশীল হতে হবে এবং প্রদত্ত সীমাবদ্ধতার (স্বতন্ত্রতা, ডিফল্ট বৈশিষ্ট্যের সাথে সম্ভাব্য সংঘর্ষ) সহ সহজতম কীগুলি নির্বাচন করুন।

দ্রষ্টব্য: অনন্য কীগুলি সংজ্ঞা অনুসারে সংঘর্ষ হয় না, তবে সম্ভাব্য হ্যাশ সংঘর্ষ অন্তর্নিহিত দ্বারা পরিচালিত হবে Object

আপনি কেন শিল্প সমাধান পছন্দ করেন না?

আইএমএইচও, সেরা কোডটি মোটেই কোনও কোড নয়: এর কোনও ত্রুটি নেই, কোনও রক্ষণাবেক্ষণের প্রয়োজন নেই, বোঝা সহজ এবং তাত্ক্ষণিকভাবে কার্যকর করা হয়। আমি দেখেছি সমস্ত "জাভাস্ক্রিপ্টের হ্যাশ টেবিলগুলি"> কোডের 100 টি লাইন ছিল এবং এতে একাধিক বস্তু জড়িত। সঙ্গে এটি তুলনা করুন: dict[key] = value

আরেকটি বিষয়: জাভা স্ক্রিপ্ট এবং খুব একই আদিম বস্তু যা ইতিমধ্যে বাস্তবায়িত হয়েছে তা বাস্তবায়নের জন্য নিম্ন স্তরের ভাষায় লিখিত কোনও আদিম বস্তুটির পারফরম্যান্সকে হারানো কি সম্ভব?

আমি এখনও কোনও কী ছাড়াই আমার জিনিসগুলি হ্যাশ করতে চাই!

আমরা ভাগ্যে আছি: ইসমাস্ক্রিপ্ট 2015 (২০১৫ সালের মাঝামাঝি সময়ে প্রকাশের জন্য নির্ধারিত, এর পরে ব্যাপক হওয়ার জন্য 1-2 বছর দিন বা দিন) ম্যাপটি নির্ধারণ করে এবং সেট করে

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

এমডিএন থেকে তুলনা ব্রেকডাউন :

অবজেক্টস মানচিত্রের সমান যা উভয়ই আপনাকে মানগুলির কীগুলি সেট করতে দেয়, সেই মানগুলি পুনরুদ্ধার করতে, কীগুলি মুছতে এবং কোনও কীতে কোনও কিছু সঞ্চিত আছে কিনা তা সনাক্ত করতে দেয়। এর কারণে (এবং কোনও অন্তর্নির্মিত বিকল্প ছিল না বলে), অবজেক্টগুলি Mapsতিহাসিকভাবে মানচিত্র হিসাবে ব্যবহৃত হয়েছে; তবে, কিছু গুরুত্বপূর্ণ পার্থক্য রয়েছে যা নির্দিষ্ট ক্ষেত্রে মানচিত্রকে ব্যবহারযোগ্য করে তোলে:

  • কোনও অবজেক্টের কীগুলি হ'ল স্ট্রিংস এবং সিম্বলস, যেখানে এগুলি ফাংশন, অবজেক্ট এবং যে কোনও আদিম সহ মানচিত্রের কোনও মান হতে পারে।
  • মানচিত্রে কীগুলি অর্ডার করা হয় যখন অবজেক্টে যুক্ত কীগুলি হয় না। সুতরাং, এটির উপরে পুনরাবৃত্তি করার সময়, একটি মানচিত্র অবজেক্ট সন্নিবেশ অনুসারে কীগুলি ফিরিয়ে দেয়।
  • আকারের বৈশিষ্ট্য সহ আপনি একটি মানচিত্রের আকার সহজেই পেতে পারেন, যখন কোনও অবজেক্টের বৈশিষ্ট্যের সংখ্যাটি ম্যানুয়ালি নির্ধারণ করতে হবে।
  • একটি মানচিত্র একটি পুনরাবৃত্ত এবং এটি সরাসরি পুনরাবৃত্তি হতে পারে, যখন কোনও বস্তুর উপর পুনরাবৃত্তি করার জন্য কিছু ফ্যাশনে এর কীগুলি গ্রহণ করা এবং সেগুলির উপরে পুনরাবৃত্তি প্রয়োজন।
  • কোনও অবজেক্টের একটি প্রোটোটাইপ রয়েছে, সুতরাং মানচিত্রে এমন ডিফল্ট কী রয়েছে যা আপনি যদি যত্নশীল না হন তবে আপনার কীগুলির সাথে সংঘর্ষে পড়তে পারে। ES5 হিসাবে এটি মানচিত্র = অবজেক্ট.ক্রিয়েট (নাল) ব্যবহার করে বাইপাস করা যেতে পারে তবে এটি খুব কমই সম্পন্ন হয়।
  • একটি মানচিত্র ঘন ঘন সংযোজন এবং কী জোড়া মুছে ফেলার জড়িত পরিস্থিতিতে আরও ভাল পারফর্ম করতে পারে।

13
এটি যথাযথ মানচিত্রের মতো দেখাচ্ছে না কারণ আপনি সংঘর্ষগুলি পরিচালনা করেন না। যদি এটি সত্য হয়ে থাকে: হ্যাশ (1জেক্ট 1) == হ্যাশ (আপত্তি 2), আপনি আপনার ডেটা হারাতে চলেছেন।
মৌমাছিদের 4

32
"পল অ্যানলে" এবং "পলা ইনলে" উভয়ই আপনার সিস্টেমে নিবন্ধ করলে স্বর্গ আপনাকে সাহায্য করে ...
ম্যাট আর

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

6
@ ইউজিনলজুতকিন - আপনি এখনও ভুল হয়ে গেছেন, আমি ভয় করি। আপনার উদাহরণটি এখনও হ্যাশের সংঘর্ষের ঝুঁকিতে রয়েছে। ভাববেন না যে কেবলমাত্র প্রথম নামটি রাখা কোনওভাবে আপনাকে সহায়তা করবে!
ম্যাট আর

3
@ ইউজিনলাজটকিন বেশিরভাগ লোকেরা আপনার এই উত্তরটি উত্তর ES6 এমনকি প্রকাশের আগে পড়ে না পড়েন ... আপনার গভীর জেএস জ্ঞানের জন্য আমাকে অভিনন্দন জানাতে দিন।
গ্যাব্রিয়েল অ্যান্ড্রেস ব্র্যাঙ্কোলিনী

171

সমস্যার বিবরণ

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

Usings মানচিত্র বস্তু, তখন আপনার মনে রাখতে যে কী এর মাধ্যমে একটি স্ট্রিং মান রূপান্তরিত হবে আছে toString(), যা ম্যাপিং ফলাফল 5এবং '5'একই মান এবং সমস্ত বস্তু যা ওভাররাইট না toString()দ্বারা সূচীবদ্ধ মান পদ্ধতি '[object Object]'। আপনি যদি চেক না করেন তবে অনিচ্ছাকৃতভাবে এর উত্তরাধিকারসূত্রে প্রাপ্ত বৈশিষ্ট্যগুলিতে অ্যাক্সেসও করতে পারেন hasOwnProperty()

জাভাস্ক্রিপ্টের অন্তর্নির্মিত অ্যারে প্রকারটি কিছুটা সাহায্য করে না: জাভাস্ক্রিপ্ট অ্যারেগুলি সংঘবদ্ধ অ্যারে নয়, তবে আরও কয়েকটি বিশেষ বৈশিষ্ট্যযুক্ত অবজেক্ট। সেগুলি কেন মানচিত্র হিসাবে ব্যবহার করা যায় না তা যদি আপনি জানতে চান তবে এখানে দেখুন

ইউজিনের সমাধান

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

  • দ্রষ্টব্য: হ্যাশ টেবিলগুলি (কখনও কখনও হ্যাশ ম্যাপস নামে পরিচিত ) হ'ল সংখ্যার হ্যাশ মানগুলির মাধ্যমে ব্যাকিং অ্যারে এবং অনুসন্ধানের সাহায্যে মানচিত্রের ধারণার একটি বিশেষ বাস্তবায়ন। রানটাইম এনভায়রনমেন্ট জাভাস্ক্রিপ্ট অবজেক্ট বাস্তবায়নের জন্য অন্যান্য কাঠামো (যেমন অনুসন্ধানের গাছ বা বাদ দেওয়া তালিকাগুলি ) ব্যবহার করতে পারে তবে বস্তুগুলি মৌলিক ডেটা কাঠামো হওয়ায় এগুলি পর্যাপ্তভাবে অনুকূলিত হওয়া উচিত।

স্বেচ্ছাসেবী বস্তুর জন্য একটি অনন্য হ্যাশ মান পেতে, একটি সম্ভাবনা হ'ল একটি বৈশ্বিক কাউন্টার ব্যবহার করা এবং হ্যাশ মানটি বস্তুটিতেই ক্যাশে করা (যেমন নামের কোনও সম্পত্তিতে __hash)।

একটি হ্যাশ ফাংশন যা এটি করে এবং আদিম মান এবং বস্তু উভয়ের জন্য কাজ করে তা হ'ল:

function hash(value) {
    return (typeof value) + ' ' + (value instanceof Object ?
        (value.__hash || (value.__hash = ++arguments.callee.current)) :
        value.toString());
}

hash.current = 0;

এই ফাংশনটি ইউজিনের বর্ণিত হিসাবে ব্যবহার করা যেতে পারে। সুবিধার জন্য, আমরা এটি আরও Mapক্লাসে আবদ্ধ করব ।

আমার Mapবাস্তবায়ন

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

// linking the key-value-pairs is optional
// if no argument is provided, linkItems === undefined, i.e. !== false
// --> linking will be enabled
function Map(linkItems) {
    this.current = undefined;
    this.size = 0;

    if(linkItems === false)
        this.disableLinking();
}

Map.noop = function() {
    return this;
};

Map.illegal = function() {
    throw new Error("illegal operation for maps without linking");
};

// map initialisation from existing object
// doesn't add inherited properties if not explicitly instructed to:
// omitting foreignKeys means foreignKeys === undefined, i.e. == false
// --> inherited properties won't be added
Map.from = function(obj, foreignKeys) {
    var map = new Map;

    for(var prop in obj) {
        if(foreignKeys || obj.hasOwnProperty(prop))
            map.put(prop, obj[prop]);
    }

    return map;
};

Map.prototype.disableLinking = function() {
    this.link = Map.noop;
    this.unlink = Map.noop;
    this.disableLinking = Map.noop;
    this.next = Map.illegal;
    this.key = Map.illegal;
    this.value = Map.illegal;
    this.removeAll = Map.illegal;

    return this;
};

// overwrite in Map instance if necessary
Map.prototype.hash = function(value) {
    return (typeof value) + ' ' + (value instanceof Object ?
        (value.__hash || (value.__hash = ++arguments.callee.current)) :
        value.toString());
};

Map.prototype.hash.current = 0;

// --- mapping functions

Map.prototype.get = function(key) {
    var item = this[this.hash(key)];
    return item === undefined ? undefined : item.value;
};

Map.prototype.put = function(key, value) {
    var hash = this.hash(key);

    if(this[hash] === undefined) {
        var item = { key : key, value : value };
        this[hash] = item;

        this.link(item);
        ++this.size;
    }
    else this[hash].value = value;

    return this;
};

Map.prototype.remove = function(key) {
    var hash = this.hash(key);
    var item = this[hash];

    if(item !== undefined) {
        --this.size;
        this.unlink(item);

        delete this[hash];
    }

    return this;
};

// only works if linked
Map.prototype.removeAll = function() {
    while(this.size)
        this.remove(this.key());

    return this;
};

// --- linked list helper functions

Map.prototype.link = function(item) {
    if(this.size == 0) {
        item.prev = item;
        item.next = item;
        this.current = item;
    }
    else {
        item.prev = this.current.prev;
        item.prev.next = item;
        item.next = this.current;
        this.current.prev = item;
    }
};

Map.prototype.unlink = function(item) {
    if(this.size == 0)
        this.current = undefined;
    else {
        item.prev.next = item.next;
        item.next.prev = item.prev;
        if(item === this.current)
            this.current = item.next;
    }
};

// --- iterator functions - only work if map is linked

Map.prototype.next = function() {
    this.current = this.current.next;
};

Map.prototype.key = function() {
    return this.current.key;
};

Map.prototype.value = function() {
    return this.current.value;
};

উদাহরণ

নিম্নলিখিত লিপি

var map = new Map;

map.put('spam', 'eggs').
    put('foo', 'bar').
    put('foo', 'baz').
    put({}, 'an object').
    put({}, 'another object').
    put(5, 'five').
    put(5, 'five again').
    put('5', 'another five');

for(var i = 0; i++ < map.size; map.next())
    document.writeln(map.hash(map.key()) + ' : ' + map.value());

এই আউটপুট উত্পন্ন:

string spam : eggs
string foo : baz
object 1 : an object
object 2 : another object
number 5 : five again
string 5 : another five

আরও বিবেচনা

PEZ toString()সম্ভবত আমাদের হ্যাশ ফাংশনটি সহ পদ্ধতিটি ওভাররাইট করার পরামর্শ দিয়েছিল । এটি সম্ভাব্য নয় কারণ এটি আদিম মানের জন্য কাজ করে না (আদিমদের toString()জন্য পরিবর্তন করা খুব খারাপ ধারণা)। আমরা যদি toString()স্বেচ্ছাচারিতামূলক বস্তুর জন্য অর্থবহ মানগুলি ফিরিয়ে দিতে চাই তবে আমাদের সংশোধন করতে হবে Object.prototype, যা কিছু লোক (আমার অন্তর্ভুক্ত নয়) ভার্বোটেন হিসাবে বিবেচনা করে ।


সম্পাদনা করুন: আমার Mapবাস্তবায়নের বর্তমান সংস্করণ পাশাপাশি অন্যান্য জাভাস্ক্রিপ্ট গুডিও এখান থেকে পাওয়া যাবে


ইএস 5 ক্যালির ব্যবহারকে হ্রাস করে ( goo.gl/EeStE )। পরিবর্তে, আমি প্রস্তাব দিচ্ছি Map._counter = 0, এবং মানচিত্রের কনস্ট্রাক্টরটি করব this._hash = 'object ' + Map._counter++। তারপরে হ্যাশ () হয়ে যায়return (value && value._hash) || (typeof(value) + ' ' + String(value));
18:41 এ 11

কোডে লিঙ্কটি অসম্পূর্ণ: mercurial.intuxication.org/hg/js-hacks/raw-file/tip/map.js
ahcox

হাই @ ক্রিসটফ, আমি যেখানে আপনার মানচিত্রের প্রয়োগটি পেতে পারি তার লিঙ্কটি আপডেট করতে পারবেন?
নিউম্যানরফরাইফ


57

আমি জানি এই প্রশ্নটি বেশ পুরানো, তবে বাইরের লাইব্রেরিগুলির সাথে আজকাল কিছু সত্যিকারের দুর্দান্ত সমাধান রয়েছে।

জাভাস্ক্রিপ্ট এর পাশাপাশি এর ভাষা সরবরাহ করেছে Map


2
এটি একবিংশ শতাব্দীতে এগিয়ে যাওয়ার উপায়। খুব খারাপ যে আমি কিছু কুৎসিত বাড়ির তৈরি মানচিত্র দিয়ে আমার কোড শেষ করার পরে আপনার পোস্টটি পেয়েছি। আপনার উত্তরের জন্য আমাদের আরও ভোটের প্রয়োজন
ফুং ডি আন

1
কালেকশন.জেএস এর কিছু বাস্তবায়ন রয়েছে, তবে আমি আন্ডারস্কোর.জেএস বা লোডাশের মধ্যে কোনওটি খুঁজে পাই না ... আপনি কী আন্ডারস্কোরটিতে উল্লেখ করবেন যা দরকারী হবে?
কোডব্লিং

@ কোডব্লিংয়ের কোনও ধারণা নেই। আমি মনে করি এটি আমি মানচিত্রের ফাংশন দিয়ে বিভ্রান্ত করেছি। আমি উত্তর থেকে এটি সরাতে যাচ্ছি।
জামেল টমস

3
এটা সঙ্গত. কালেকশন.জেএস-কে বিবেচনা করা যে কোনও ব্যক্তিকে সচেতন হওয়া উচিত যে এটি একটি সমস্যাযুক্ত ফ্যাশনে বিশ্বব্যাপী অ্যারে, ফাংশন, অবজেক্ট এবং রিজেক্সপেট প্রোটোটাইপগুলিকে সংশোধন করে ( আমি এখানে যে সমস্যাগুলি सामना করেছি সেগুলি দেখুন )। যদিও আমি প্রাথমিকভাবে সংগ্রহ.জেএসএস (এবং এই উত্তর) দিয়ে খুব সন্তুষ্ট ছিলাম, এটি ব্যবহারের সাথে যুক্ত ঝুঁকিগুলি খুব বেশি ছিল, তাই আমি এটিকে ফেলে দিয়েছি। সংগ্রহে.জেএস-এর কেবল ক্রিসকোলের v2 শাখা (বিশেষত, v2.0.2 +) বিশ্বব্যাপী প্রোটোটাইপ পরিবর্তনগুলি মুছে ফেলে এবং ব্যবহারে নিরাপদ।
25:40

28

জাভা মানচিত্রের অনুরূপ কিছু ব্যবহার করার এখানে একটি সহজ এবং সুবিধাজনক উপায়:

var map= {
        'map_name_1': map_value_1,
        'map_name_2': map_value_2,
        'map_name_3': map_value_3,
        'map_name_4': map_value_4
        }

এবং মান পেতে:

alert( map['map_name_1'] );    // fives the value of map_value_1

......  etc  .....

2
এটি কেবল স্ট্রিং কীগুলির জন্য কাজ করে। আমি বিশ্বাস করি যে ওপি কোনও প্রকারের কী ব্যবহার করতে আগ্রহী ছিল।
ফ্র্যাক্টর

26

ECMAScript 2015 (ES6) অনুসারে স্ট্যান্ডার্ড জাভাস্ক্রিপ্টটিতে মানচিত্রের প্রয়োগ রয়েছে। যা সম্পর্কে আরও এখানে পাওয়া যাবে

বেসিক ব্যবহার:

var myMap = new Map();
var keyString = "a string",
    keyObj = {},
    keyFunc = function () {};

// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

myMap.size; // 3

// getting the values
myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

21

আপনি ES6 WeakMapবা ব্যবহার করতে পারেন Map:

  • WeakMaps কী / মান মানচিত্র যা কী অবজেক্ট হয়।

  • Mapঅবজেক্টগুলি সহজ কী / মান মানচিত্র। যে কোনও মান (উভয় বস্তু এবং আদিম মান) একটি কী বা মান হিসাবে ব্যবহৃত হতে পারে।

উভয়টিই ব্যাপকভাবে সমর্থিত নয়, তবে আপনি সমর্থন করতে ES6 শিম (নেটিভ ES5 বা ES5 শিমের প্রয়োজন ) ব্যবহার করতে পারেন Mapতবে তা WeakMap( কেন নয় ) তা জেনে রাখুন


2019 এ তারা খুব ভাল সমর্থিত এবং আশ্চর্যজনক পদ্ধতি রয়েছে! বিকাশকারী.মোজিলা.আর.ইন-
ইউএস

13

আপনাকে কিছু অভ্যন্তরীণ স্টেট দম্পতি / অবজেক্ট / মান জোড়া সংরক্ষণ করতে হবে

HashMap = function(){
  this._dict = [];
}
HashMap.prototype._get = function(key){
  for(var i=0, couplet; couplet = this._dict[i]; i++){
    if(couplet[0] === key){
      return couplet;
    }
  }
}
HashMap.prototype.put = function(key, value){
  var couplet = this._get(key);
  if(couplet){
    couplet[1] = value;
  }else{
    this._dict.push([key, value]);
  }
  return this; // for chaining
}
HashMap.prototype.get = function(key){
  var couplet = this._get(key);
  if(couplet){
    return couplet[1];
  }
}

এবং এটি যেমন ব্যবহার করুন:

var color = {}; // unique object instance
var shape = {}; // unique object instance
var map = new HashMap();
map.put(color, "blue");
map.put(shape, "round");
console.log("Item is", map.get(color), "and", map.get(shape));

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

হালনাগাদ:

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

HashMap = function(){
  this._dict = {};
}
HashMap.prototype._shared = {id: 1};
HashMap.prototype.put = function put(key, value){
  if(typeof key == "object"){
    if(!key.hasOwnProperty._id){
      key.hasOwnProperty = function(key){
        return Object.prototype.hasOwnProperty.call(this, key);
      }
      key.hasOwnProperty._id = this._shared.id++;
    }
    this._dict[key.hasOwnProperty._id] = value;
  }else{
    this._dict[key] = value;
  }
  return this; // for chaining
}
HashMap.prototype.get = function get(key){
  if(typeof key == "object"){
    return this._dict[key.hasOwnProperty._id];
  }
  return this._dict[key];
}

এই সংস্করণটি কেবলমাত্র সামান্য দ্রুত বলে মনে হচ্ছে, তবে তাত্ত্বিকভাবে এটি বড় ডেটা সেটগুলির জন্য উল্লেখযোগ্যভাবে দ্রুত হবে।


একটি সহযোগী অ্যারে, অর্থাত্ 2-টিপলগুলির একটি অ্যারে মানচিত্র, কোনও হ্যাশম্যাপ নয়; একটি হ্যাশম্যাপ এমন মানচিত্র যা আরও ভাল পারফরম্যান্সের জন্য হ্যাশ ব্যবহার করে।
এরিক কাপলুন

সত্য, তবে কেন বিষয়টিতে চুল বিভক্ত? জাভাস্ক্রিপ্টে সত্যিকারের হ্যাশ মানচিত্র তৈরি করার কোনও উপায় নেই যেহেতু আপনি অবজেক্ট মেমরির ঠিকানা পেতে পারেন না। এবং জাভাস্ক্রিপ্টের অন্তর্নির্মিত অবজেক্ট কী / মান জোড়া (আমার দ্বিতীয় উদাহরণে ব্যবহৃত) হ্যাশম্যাপস হিসাবে কাজ করতে পারে তবে অগত্যা নয়, কারণ এটি ব্রাউজারে কীভাবে চেহারাটি প্রয়োগ করা হয় তা রানটাইম পর্যন্ত ব্যবহৃত হয়।
pottedmeat

11

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

function HashMap() {
    this.buckets = {};
}

HashMap.prototype.put = function(key, value) {
    var hashCode = key.hashCode();
    var bucket = this.buckets[hashCode];
    if (!bucket) {
        bucket = new Array();
        this.buckets[hashCode] = bucket;
    }
    for (var i = 0; i < bucket.length; ++i) {
        if (bucket[i].key.equals(key)) {
            bucket[i].value = value;
            return;
        }
    }
    bucket.push({ key: key, value: value });
}

HashMap.prototype.get = function(key) {
    var hashCode = key.hashCode();
    var bucket = this.buckets[hashCode];
    if (!bucket) {
        return null;
    }
    for (var i = 0; i < bucket.length; ++i) {
        if (bucket[i].key.equals(key)) {
            return bucket[i].value;
        }
    }
}

HashMap.prototype.keys = function() {
    var keys = new Array();
    for (var hashKey in this.buckets) {
        var bucket = this.buckets[hashKey];
        for (var i = 0; i < bucket.length; ++i) {
            keys.push(bucket[i].key);
        }
    }
    return keys;
}

HashMap.prototype.values = function() {
    var values = new Array();
    for (var hashKey in this.buckets) {
        var bucket = this.buckets[hashKey];
        for (var i = 0; i < bucket.length; ++i) {
            values.push(bucket[i].value);
        }
    }
    return values;
}

দ্রষ্টব্য: মূল বিষয়গুলি অবশ্যই হ্যাশকোড () এবং সমান () পদ্ধতিগুলি "প্রয়োগ" করতে হবে।


7
new Array()ওভারের অগ্রাধিকারটি []কি আপনার কোডের পরম জাভা-সামঞ্জস্যতা নিশ্চিত করা? :)
এরিক কাপলুন

6

আমি একটি জাভাস্ক্রিপ্ট হ্যাশম্যাপ প্রয়োগ করেছি যা http://github.com/lambder/HashMapJS/tree/master থেকে কোড প্রাপ্ত হতে পারে

কোডটি এখানে:

/*
 =====================================================================
 @license MIT
 @author Lambder
 @copyright 2009 Lambder.
 @end
 =====================================================================
 */
var HashMap = function() {
  this.initialize();
}

HashMap.prototype = {
  hashkey_prefix: "<#HashMapHashkeyPerfix>",
  hashcode_field: "<#HashMapHashkeyPerfix>",

  initialize: function() {
    this.backing_hash = {};
    this.code = 0;
  },
  /*
   maps value to key returning previous assocciation
   */
  put: function(key, value) {
    var prev;
    if (key && value) {
      var hashCode = key[this.hashcode_field];
      if (hashCode) {
        prev = this.backing_hash[hashCode];
      } else {
        this.code += 1;
        hashCode = this.hashkey_prefix + this.code;
        key[this.hashcode_field] = hashCode;
      }
      this.backing_hash[hashCode] = value;
    }
    return prev;
  },
  /*
   returns value associated with given key
   */
  get: function(key) {
    var value;
    if (key) {
      var hashCode = key[this.hashcode_field];
      if (hashCode) {
        value = this.backing_hash[hashCode];
      }
    }
    return value;
  },
  /*
   deletes association by given key.
   Returns true if the assocciation existed, false otherwise
   */
  del: function(key) {
    var success = false;
    if (key) {
      var hashCode = key[this.hashcode_field];
      if (hashCode) {
        var prev = this.backing_hash[hashCode];
        this.backing_hash[hashCode] = undefined;
        if(prev !== undefined)
          success = true;
      }
    }
    return success;
  }
}

//// Usage

// creation

var my_map = new HashMap();

// insertion

var a_key = {};
var a_value = {struct: "structA"};
var b_key = {};
var b_value = {struct: "structB"};
var c_key = {};
var c_value = {struct: "structC"};

my_map.put(a_key, a_value);
my_map.put(b_key, b_value);
var prev_b = my_map.put(b_key, c_value);

// retrieval

if(my_map.get(a_key) !== a_value){
  throw("fail1")
}
if(my_map.get(b_key) !== c_value){
  throw("fail2")
}
if(prev_b !== b_value){
  throw("fail3")
}

// deletion

var a_existed = my_map.del(a_key);
var c_existed = my_map.del(c_key);
var a2_existed = my_map.del(a_key);

if(a_existed !== true){
  throw("fail4")
}
if(c_existed !== false){
  throw("fail5")
}
if(a2_existed !== false){
  throw("fail6")
}

2
আপনার কোডটি একই জিনিসটি একাধিক HashMapসতে রেখে কাজ করবে বলে মনে হচ্ছে না ।
এরিক কাপলুন

5

ইসিএমএ 6 এ আপনি উইকম্যাপ ব্যবহার করতে পারেন

উদাহরণ:

var wm1 = new WeakMap(),
    wm2 = new WeakMap(),
    wm3 = new WeakMap();
var o1 = {},
    o2 = function(){},
    o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // a value can be anything, including an object or a function
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // keys and values can be any objects. Even WeakMaps!

wm1.get(o2); // "azerty"
wm2.get(o2); // undefined, because there is no value for o2 on wm2
wm2.get(o3); // undefined, because that is the set value

wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (even if the value itself is 'undefined')

wm3.set(o1, 37);
wm3.get(o1); // 37
wm3.clear();
wm3.get(o1); // undefined, because wm3 was cleared and there is no value for o1 anymore

wm1.has(o1);   // true
wm1.delete(o1);
wm1.has(o1);   // false

কিন্তু:

Because of references being weak, WeakMap keys are not enumerable (i.e. there is no method giving you a list of the keys). 

ওহ প্রশংসা করুন যীশু তারা শেষ পর্যন্ত জাভাস্ক্রিপ্টে দুর্বল উল্লেখ যুক্ত করছেন। এটি প্রায় সময় ... +1 এর জন্য, তবে এটি ব্যবহার করা আসলেই ভয়ঙ্কর হবে কারণ উল্লেখগুলি দুর্বল
ক্লাদিউ

2

জাভাস্ক্রিপ্ট ম্যাপ / হ্যাশম্যাপ বিল্ট-ইন করে না। এটিকে এসোসিয়েটিভ অ্যারে বলা উচিত ।

hash["X"]এর সমান hash.X, তবে স্ট্রিং ভেরিয়েবল হিসাবে "এক্স" এর অনুমতি দিন। অন্য কথায়, hash[x]কার্যত সমানeval("hash."+x.toString())

এটি অবজেক্ট.প্রোপার্টিগুলির চেয়ে আরও অনুরূপ তবে কী-মান ম্যাপিং। আপনি যদি জাভাস্ক্রিপ্টে আরও ভাল কী / মান মানচিত্রের সন্ধান করছেন, দয়া করে মানচিত্রে অবজেক্টটি ব্যবহার করুন যা আপনি ওয়েবে খুঁজে পেতে পারেন।


2

আমার জাভাস্ক্রিপ্ট হ্যাশ টেবিল বাস্তবায়ন চেষ্টা করুন: http://www.timdown.co.uk/jshashtable

এটি মূল বিষয়গুলির হ্যাশকোড () পদ্ধতির সন্ধান করে বা হ্যাশটেবল অবজেক্ট তৈরি করার সময় আপনি একটি হ্যাশিং ফাংশন সরবরাহ করতে পারেন।


2

এটি দেখতে বেশ শক্তিশালী সমাধানের মতো দেখাচ্ছে: https://github.com/flesler/hashmap । এমনকি এটি একই রকম দেখায় এমন ফাংশন এবং অবজেক্টগুলির জন্য ভাল কাজ করবে। এটি কেবলমাত্র হ্যাকটি ব্যবহার করে এটি সনাক্ত করার জন্য কোনও অস্পষ্ট সদস্যকে যুক্ত করা হচ্ছে। যদি আপনার প্রোগ্রামটি সেই অস্পষ্ট পরিবর্তনশীলটিকে ওভাররাইট না করে (এটি হ্যাশিডের মতো কিছু ) তবে আপনি সোনার।


2

তাহলে কর্মক্ষমতা সমালোচনামূলক নয় (যেমন কী পরিমাণ অপেক্ষাকৃত ছোট হয়) এবং আপনি দূষিত মত অতিরিক্ত ক্ষেত্রের সাথে আপনার (হয়তো বা না আপনার) বস্তু চাই না _hash, _idইত্যাদি,, তাহলে আপনি যে ব্যবহার করতে পারেন Array.prototype.indexOfনিয়োগ কঠোর সাম্য। এখানে একটি সহজ বাস্তবায়ন:

var Dict = (function(){
    // IE 8 and earlier has no Array.prototype.indexOf
    function indexOfPolyfill(val) {
      for (var i = 0, l = this.length; i < l; ++i) {
        if (this[i] === val) {
          return i;
        }
      }
      return -1;
    }

    function Dict(){
      this.keys = [];
      this.values = [];
      if (!this.keys.indexOf) {
        this.keys.indexOf = indexOfPolyfill;
      }
    };

    Dict.prototype.has = function(key){
      return this.keys.indexOf(key) != -1;
    };

    Dict.prototype.get = function(key, defaultValue){
      var index = this.keys.indexOf(key);
      return index == -1 ? defaultValue : this.values[index];
    };

    Dict.prototype.set = function(key, value){
      var index = this.keys.indexOf(key);
      if (index == -1) {
        this.keys.push(key);
        this.values.push(value);
      } else {
        var prevValue = this.values[index];
        this.values[index] = value;
        return prevValue;
      }
    };

    Dict.prototype.delete = function(key){
      var index = this.keys.indexOf(key);
      if (index != -1) {
        this.keys.splice(index, 1);
        return this.values.splice(index, 1)[0];
      }
    };

    Dict.prototype.clear = function(){
      this.keys.splice(0, this.keys.length);
      this.values.splice(0, this.values.length);
    };

    return Dict;
})();

ব্যবহারের উদাহরণ:

var a = {}, b = {},
    c = { toString: function(){ return '1'; } },
    d = 1, s = '1', u = undefined, n = null,
    dict = new Dict();

// keys and values can be anything
dict.set(a, 'a');
dict.set(b, 'b');
dict.set(c, 'c');
dict.set(d, 'd');
dict.set(s, 's');
dict.set(u, 'u');
dict.set(n, 'n');

dict.get(a); // 'a'
dict.get(b); // 'b'
dict.get(s); // 's'
dict.get(u); // 'u'
dict.get(n); // 'n'
// etc.

ES6 WeakMap এর সাথে তুলনা করে এটিতে দুটি সমস্যা রয়েছে: ও (এন) অনুসন্ধানের সময় এবং অ-দুর্বলতা (অর্থাত্ যদি আপনি কীগুলি ব্যবহার না করেন deleteবা clearরিলিজ না করেন তবে এটি মেমরি ফাঁসির কারণ হবে )।


2

আমার মানচিত্র বাস্তবায়ন, ক্রিস্টফের উদাহরণ থেকে প্রাপ্ত:

ব্যবহারের উদাহরণ:

var map = new Map();  //creates an "in-memory" map
var map = new Map("storageId");  //creates a map that is loaded/persisted using html5 storage

function Map(storageId) {
    this.current = undefined;
    this.size = 0;
    this.storageId = storageId;
    if (this.storageId) {
        this.keys = new Array();
        this.disableLinking();
    }
}

Map.noop = function() {
    return this;
};

Map.illegal = function() {
    throw new Error("illegal operation for maps without linking");
};

// map initialisation from existing object
// doesn't add inherited properties if not explicitly instructed to:
// omitting foreignKeys means foreignKeys === undefined, i.e. == false
// --> inherited properties won't be added
Map.from = function(obj, foreignKeys) {
    var map = new Map;
    for(var prop in obj) {
        if(foreignKeys || obj.hasOwnProperty(prop))
            map.put(prop, obj[prop]);
    }
    return map;
};

Map.prototype.disableLinking = function() {
    this.link = Map.noop;
    this.unlink = Map.noop;
    this.disableLinking = Map.noop;

    this.next = Map.illegal;
    this.key = Map.illegal;
    this.value = Map.illegal;
//    this.removeAll = Map.illegal;


    return this;
};

// overwrite in Map instance if necessary
Map.prototype.hash = function(value) {
    return (typeof value) + ' ' + (value instanceof Object ?
        (value.__hash || (value.__hash = ++arguments.callee.current)) :
        value.toString());
};

Map.prototype.hash.current = 0;

// --- mapping functions

Map.prototype.get = function(key) {
    var item = this[this.hash(key)];
    if (item === undefined) {
        if (this.storageId) {
            try {
                var itemStr = localStorage.getItem(this.storageId + key);
                if (itemStr && itemStr !== 'undefined') {
                    item = JSON.parse(itemStr);
                    this[this.hash(key)] = item;
                    this.keys.push(key);
                    ++this.size;
                }
            } catch (e) {
                console.log(e);
            }
        }
    }
    return item === undefined ? undefined : item.value;
};

Map.prototype.put = function(key, value) {
    var hash = this.hash(key);

    if(this[hash] === undefined) {
        var item = { key : key, value : value };
        this[hash] = item;

        this.link(item);
        ++this.size;
    }
    else this[hash].value = value;
    if (this.storageId) {
        this.keys.push(key);
        try {
            localStorage.setItem(this.storageId + key, JSON.stringify(this[hash]));
        } catch (e) {
            console.log(e);
        }
    }
    return this;
};

Map.prototype.remove = function(key) {
    var hash = this.hash(key);
    var item = this[hash];
    if(item !== undefined) {
        --this.size;
        this.unlink(item);

        delete this[hash];
    }
    if (this.storageId) {
        try {
            localStorage.setItem(this.storageId + key, undefined);
        } catch (e) {
            console.log(e);
        }
    }
    return this;
};

// only works if linked
Map.prototype.removeAll = function() {
    if (this.storageId) {
        for (var i=0; i<this.keys.length; i++) {
            this.remove(this.keys[i]);
        }
        this.keys.length = 0;
    } else {
        while(this.size)
            this.remove(this.key());
    }
    return this;
};

// --- linked list helper functions

Map.prototype.link = function(item) {
    if (this.storageId) {
        return;
    }
    if(this.size == 0) {
        item.prev = item;
        item.next = item;
        this.current = item;
    }
    else {
        item.prev = this.current.prev;
        item.prev.next = item;
        item.next = this.current;
        this.current.prev = item;
    }
};

Map.prototype.unlink = function(item) {
    if (this.storageId) {
        return;
    }
    if(this.size == 0)
        this.current = undefined;
    else {
        item.prev.next = item.next;
        item.next.prev = item.prev;
        if(item === this.current)
            this.current = item.next;
    }
};

// --- iterator functions - only work if map is linked

Map.prototype.next = function() {
    this.current = this.current.next;
};

Map.prototype.key = function() {
    if (this.storageId) {
        return undefined;
    } else {
        return this.current.key;
    }
};

Map.prototype.value = function() {
    if (this.storageId) {
        return undefined;
    }
    return this.current.value;
};

1

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

প্রকল্পটি এখানে পাওয়া যাবে: https://github.com/Airblader/jsava আমি হ্যাশম্যাপ শ্রেণীর জন্য (বর্তমান) উত্স কোডটিও সংযুক্ত করব, তবে যেমনটি বলা হয়েছে এটি সুপার ক্লাস ইত্যাদির উপরও নির্ভর করে The Qooxdoo হয়।

সম্পাদনা করুন: দয়া করে নোট করুন যে এই কোডটি ইতিমধ্যে সেকেলে এবং বর্তমান কাজের জন্য গিথুব প্রকল্পটি দেখুন। এটি লেখার ক্ষেত্রে, একটি ArrayListবাস্তবায়নও রয়েছে।

qx.Class.define( 'jsava.util.HashMap', {
    extend: jsava.util.AbstractMap,
    implement: [jsava.util.Map, jsava.io.Serializable, jsava.lang.Cloneable],

    construct: function () {
        var args = Array.prototype.slice.call( arguments ),
            initialCapacity = this.self( arguments ).DEFAULT_INITIAL_CAPACITY,
            loadFactor = this.self( arguments ).DEFAULT_LOAD_FACTOR;

        switch( args.length ) {
            case 1:
                if( qx.Class.implementsInterface( args[0], jsava.util.Map ) ) {
                    initialCapacity = Math.max( ((args[0].size() / this.self( arguments ).DEFAULT_LOAD_FACTOR) | 0) + 1,
                        this.self( arguments ).DEFAULT_INITIAL_CAPACITY );
                    loadFactor = this.self( arguments ).DEFAULT_LOAD_FACTOR;
                } else {
                    initialCapacity = args[0];
                }
                break;
            case 2:
                initialCapacity = args[0];
                loadFactor = args[1];
                break;
        }

        if( initialCapacity < 0 ) {
            throw new jsava.lang.IllegalArgumentException( 'Illegal initial capacity: ' + initialCapacity );
        }
        if( initialCapacity > this.self( arguments ).MAXIMUM_CAPACITY ) {
            initialCapacity = this.self( arguments ).MAXIMUM_CAPACITY;
        }
        if( loadFactor <= 0 || isNaN( loadFactor ) ) {
            throw new jsava.lang.IllegalArgumentException( 'Illegal load factor: ' + loadFactor );
        }

        var capacity = 1;
        while( capacity < initialCapacity ) {
            capacity <<= 1;
        }

        this._loadFactor = loadFactor;
        this._threshold = (capacity * loadFactor) | 0;
        this._table = jsava.JsavaUtils.emptyArrayOfGivenSize( capacity, null );
        this._init();
    },

    statics: {
        serialVersionUID: 1,

        DEFAULT_INITIAL_CAPACITY: 16,
        MAXIMUM_CAPACITY: 1 << 30,
        DEFAULT_LOAD_FACTOR: 0.75,

        _hash: function (hash) {
            hash ^= (hash >>> 20) ^ (hash >>> 12);
            return hash ^ (hash >>> 7) ^ (hash >>> 4);
        },

        _indexFor: function (hashCode, length) {
            return hashCode & (length - 1);
        },

        Entry: qx.Class.define( 'jsava.util.HashMap.Entry', {
            extend: jsava.lang.Object,
            implement: [jsava.util.Map.Entry],

            construct: function (hash, key, value, nextEntry) {
                this._value = value;
                this._next = nextEntry;
                this._key = key;
                this._hash = hash;
            },

            members: {
                _key: null,
                _value: null,
                /** @type jsava.util.HashMap.Entry */
                _next: null,
                /** @type Number */
                _hash: 0,

                getKey: function () {
                    return this._key;
                },

                getValue: function () {
                    return this._value;
                },

                setValue: function (newValue) {
                    var oldValue = this._value;
                    this._value = newValue;
                    return oldValue;
                },

                equals: function (obj) {
                    if( obj === null || !qx.Class.implementsInterface( obj, jsava.util.HashMap.Entry ) ) {
                        return false;
                    }

                    /** @type jsava.util.HashMap.Entry */
                    var entry = obj,
                        key1 = this.getKey(),
                        key2 = entry.getKey();
                    if( key1 === key2 || (key1 !== null && key1.equals( key2 )) ) {
                        var value1 = this.getValue(),
                            value2 = entry.getValue();
                        if( value1 === value2 || (value1 !== null && value1.equals( value2 )) ) {
                            return true;
                        }
                    }

                    return false;
                },

                hashCode: function () {
                    return (this._key === null ? 0 : this._key.hashCode()) ^
                        (this._value === null ? 0 : this._value.hashCode());
                },

                toString: function () {
                    return this.getKey() + '=' + this.getValue();
                },

                /**
                 * This method is invoked whenever the value in an entry is
                 * overwritten by an invocation of put(k,v) for a key k that's already
                 * in the HashMap.
                 */
                _recordAccess: function (map) {
                },

                /**
                 * This method is invoked whenever the entry is
                 * removed from the table.
                 */
                _recordRemoval: function (map) {
                }
            }
        } )
    },

    members: {
        /** @type jsava.util.HashMap.Entry[] */
        _table: null,
        /** @type Number */
        _size: 0,
        /** @type Number */
        _threshold: 0,
        /** @type Number */
        _loadFactor: 0,
        /** @type Number */
        _modCount: 0,
        /** @implements jsava.util.Set */
        __entrySet: null,

        /**
         * Initialization hook for subclasses. This method is called
         * in all constructors and pseudo-constructors (clone, readObject)
         * after HashMap has been initialized but before any entries have
         * been inserted.  (In the absence of this method, readObject would
         * require explicit knowledge of subclasses.)
         */
        _init: function () {
        },

        size: function () {
            return this._size;
        },

        isEmpty: function () {
            return this._size === 0;
        },

        get: function (key) {
            if( key === null ) {
                return this.__getForNullKey();
            }

            var hash = this.self( arguments )._hash( key.hashCode() );
            for( var entry = this._table[this.self( arguments )._indexFor( hash, this._table.length )];
                 entry !== null; entry = entry._next ) {
                /** @type jsava.lang.Object */
                var k;
                if( entry._hash === hash && ((k = entry._key) === key || key.equals( k )) ) {
                    return entry._value;
                }
            }

            return null;
        },

        __getForNullKey: function () {
            for( var entry = this._table[0]; entry !== null; entry = entry._next ) {
                if( entry._key === null ) {
                    return entry._value;
                }
            }

            return null;
        },

        containsKey: function (key) {
            return this._getEntry( key ) !== null;
        },

        _getEntry: function (key) {
            var hash = (key === null) ? 0 : this.self( arguments )._hash( key.hashCode() );
            for( var entry = this._table[this.self( arguments )._indexFor( hash, this._table.length )];
                 entry !== null; entry = entry._next ) {
                /** @type jsava.lang.Object */
                var k;
                if( entry._hash === hash
                    && ( ( k = entry._key ) === key || ( key !== null && key.equals( k ) ) ) ) {
                    return entry;
                }
            }

            return null;
        },

        put: function (key, value) {
            if( key === null ) {
                return this.__putForNullKey( value );
            }

            var hash = this.self( arguments )._hash( key.hashCode() ),
                i = this.self( arguments )._indexFor( hash, this._table.length );
            for( var entry = this._table[i]; entry !== null; entry = entry._next ) {
                /** @type jsava.lang.Object */
                var k;
                if( entry._hash === hash && ( (k = entry._key) === key || key.equals( k ) ) ) {
                    var oldValue = entry._value;
                    entry._value = value;
                    entry._recordAccess( this );
                    return oldValue;
                }
            }

            this._modCount++;
            this._addEntry( hash, key, value, i );
            return null;
        },

        __putForNullKey: function (value) {
            for( var entry = this._table[0]; entry !== null; entry = entry._next ) {
                if( entry._key === null ) {
                    var oldValue = entry._value;
                    entry._value = value;
                    entry._recordAccess( this );
                    return oldValue;
                }
            }

            this._modCount++;
            this._addEntry( 0, null, value, 0 );
            return null;
        },

        __putForCreate: function (key, value) {
            var hash = (key === null) ? 0 : this.self( arguments )._hash( key.hashCode() ),
                i = this.self( arguments )._indexFor( hash, this._table.length );
            for( var entry = this._table[i]; entry !== null; entry = entry._next ) {
                /** @type jsava.lang.Object */
                var k;
                if( entry._hash === hash
                    && ( (k = entry._key) === key || ( key !== null && key.equals( k ) ) ) ) {
                    entry._value = value;
                    return;
                }
            }

            this._createEntry( hash, key, value, i );
        },

        __putAllForCreate: function (map) {
            var iterator = map.entrySet().iterator();
            while( iterator.hasNext() ) {
                var entry = iterator.next();
                this.__putForCreate( entry.getKey(), entry.getValue() );
            }
        },

        _resize: function (newCapacity) {
            var oldTable = this._table,
                oldCapacity = oldTable.length;
            if( oldCapacity === this.self( arguments ).MAXIMUM_CAPACITY ) {
                this._threshold = Number.MAX_VALUE;
                return;
            }

            var newTable = jsava.JsavaUtils.emptyArrayOfGivenSize( newCapacity, null );
            this._transfer( newTable );
            this._table = newTable;
            this._threshold = (newCapacity * this._loadFactor) | 0;
        },

        _transfer: function (newTable) {
            var src = this._table,
                newCapacity = newTable.length;
            for( var j = 0; j < src.length; j++ ) {
                var entry = src[j];
                if( entry !== null ) {
                    src[j] = null;
                    do {
                        var next = entry._next,
                            i = this.self( arguments )._indexFor( entry._hash, newCapacity );
                        entry._next = newTable[i];
                        newTable[i] = entry;
                        entry = next;
                    } while( entry !== null );
                }
            }
        },

        putAll: function (map) {
            var numKeyToBeAdded = map.size();
            if( numKeyToBeAdded === 0 ) {
                return;
            }

            if( numKeyToBeAdded > this._threshold ) {
                var targetCapacity = (numKeyToBeAdded / this._loadFactor + 1) | 0;
                if( targetCapacity > this.self( arguments ).MAXIMUM_CAPACITY ) {
                    targetCapacity = this.self( arguments ).MAXIMUM_CAPACITY;
                }

                var newCapacity = this._table.length;
                while( newCapacity < targetCapacity ) {
                    newCapacity <<= 1;
                }
                if( newCapacity > this._table.length ) {
                    this._resize( newCapacity );
                }
            }

            var iterator = map.entrySet().iterator();
            while( iterator.hasNext() ) {
                var entry = iterator.next();
                this.put( entry.getKey(), entry.getValue() );
            }
        },

        remove: function (key) {
            var entry = this._removeEntryForKey( key );
            return entry === null ? null : entry._value;
        },

        _removeEntryForKey: function (key) {
            var hash = (key === null) ? 0 : this.self( arguments )._hash( key.hashCode() ),
                i = this.self( arguments )._indexFor( hash, this._table.length ),
                prev = this._table[i],
                entry = prev;

            while( entry !== null ) {
                var next = entry._next,
                    /** @type jsava.lang.Object */
                        k;
                if( entry._hash === hash
                    && ( (k = entry._key) === key || ( key !== null && key.equals( k ) ) ) ) {
                    this._modCount++;
                    this._size--;
                    if( prev === entry ) {
                        this._table[i] = next;
                    } else {
                        prev._next = next;
                    }
                    entry._recordRemoval( this );
                    return entry;
                }
                prev = entry;
                entry = next;
            }

            return entry;
        },

        _removeMapping: function (obj) {
            if( obj === null || !qx.Class.implementsInterface( obj, jsava.util.Map.Entry ) ) {
                return null;
            }

            /** @implements jsava.util.Map.Entry */
            var entry = obj,
                key = entry.getKey(),
                hash = (key === null) ? 0 : this.self( arguments )._hash( key.hashCode() ),
                i = this.self( arguments )._indexFor( hash, this._table.length ),
                prev = this._table[i],
                e = prev;

            while( e !== null ) {
                var next = e._next;
                if( e._hash === hash && e.equals( entry ) ) {
                    this._modCount++;
                    this._size--;
                    if( prev === e ) {
                        this._table[i] = next;
                    } else {
                        prev._next = next;
                    }
                    e._recordRemoval( this );
                    return e;
                }
                prev = e;
                e = next;
            }

            return e;
        },

        clear: function () {
            this._modCount++;
            var table = this._table;
            for( var i = 0; i < table.length; i++ ) {
                table[i] = null;
            }
            this._size = 0;
        },

        containsValue: function (value) {
            if( value === null ) {
                return this.__containsNullValue();
            }

            var table = this._table;
            for( var i = 0; i < table.length; i++ ) {
                for( var entry = table[i]; entry !== null; entry = entry._next ) {
                    if( value.equals( entry._value ) ) {
                        return true;
                    }
                }
            }

            return false;
        },

        __containsNullValue: function () {
            var table = this._table;
            for( var i = 0; i < table.length; i++ ) {
                for( var entry = table[i]; entry !== null; entry = entry._next ) {
                    if( entry._value === null ) {
                        return true;
                    }
                }
            }

            return false;
        },

        clone: function () {
            /** @type jsava.util.HashMap */
            var result = null;
            try {
                result = this.base( arguments );
            } catch( e ) {
                if( !qx.Class.isSubClassOf( e.constructor, jsava.lang.CloneNotSupportedException ) ) {
                    throw e;
                }
            }

            result._table = jsava.JsavaUtils.emptyArrayOfGivenSize( this._table.length, null );
            result.__entrySet = null;
            result._modCount = 0;
            result._size = 0;
            result._init();
            result.__putAllForCreate( this );

            return result;
        },

        _addEntry: function (hash, key, value, bucketIndex) {
            var entry = this._table[bucketIndex];
            this._table[bucketIndex] = new (this.self( arguments ).Entry)( hash, key, value, entry );
            if( this._size++ >= this._threshold ) {
                this._resize( 2 * this._table.length );
            }
        },

        _createEntry: function (hash, key, value, bucketIndex) {
            var entry = this._table[bucketIndex];
            this._table[bucketIndex] = new (this.self( arguments ).Entry)( hash, key, value, entry );
            this._size++;
        },

        keySet: function () {
            var keySet = this._keySet;
            return keySet !== null ? keySet : ( this._keySet = new this.KeySet( this ) );
        },

        values: function () {
            var values = this._values;
            return values !== null ? values : ( this._values = new this.Values( this ) );
        },

        entrySet: function () {
            return this.__entrySet0();
        },

        __entrySet0: function () {
            var entrySet = this.__entrySet;
            return entrySet !== null ? entrySet : ( this.__entrySet = new this.EntrySet( this ) );
        },

        /** @private */
        HashIterator: qx.Class.define( 'jsava.util.HashMap.HashIterator', {
            extend: jsava.lang.Object,
            implement: [jsava.util.Iterator],

            type: 'abstract',

            /** @protected */
            construct: function (thisHashMap) {
                this.__thisHashMap = thisHashMap;
                this._expectedModCount = this.__thisHashMap._modCount;
                if( this.__thisHashMap._size > 0 ) {
                    var table = this.__thisHashMap._table;
                    while( this._index < table.length && ( this._next = table[this._index++] ) === null ) {
                        // do nothing
                    }
                }
            },

            members: {
                __thisHashMap: null,

                /** @type jsava.util.HashMap.Entry */
                _next: null,
                /** @type Number */
                _expectedModCount: 0,
                /** @type Number */
                _index: 0,
                /** @type jsava.util.HashMap.Entry */
                _current: null,

                hasNext: function () {
                    return this._next !== null;
                },

                _nextEntry: function () {
                    if( this.__thisHashMap._modCount !== this._expectedModCount ) {
                        throw new jsava.lang.ConcurrentModificationException();
                    }

                    var entry = this._next;
                    if( entry === null ) {
                        throw new jsava.lang.NoSuchElementException();
                    }

                    if( (this._next = entry._next) === null ) {
                        var table = this.__thisHashMap._table;
                        while( this._index < table.length && ( this._next = table[this._index++] ) === null ) {
                            // do nothing
                        }
                    }

                    this._current = entry;
                    return entry;
                },

                remove: function () {
                    if( this._current === null ) {
                        throw new jsava.lang.IllegalStateException();
                    }

                    if( this.__thisHashMap._modCount !== this._expectedModCount ) {
                        throw new jsava.lang.ConcurrentModificationException();
                    }

                    var key = this._current._key;
                    this._current = null;
                    this.__thisHashMap._removeEntryForKey( key );
                    this._expectedModCount = this.__thisHashMap._modCount;
                }
            }
        } ),

        _newKeyIterator: function () {
            return new this.KeyIterator( this );
        },

        _newValueIterator: function () {
            return new this.ValueIterator( this );
        },

        _newEntryIterator: function () {
            return new this.EntryIterator( this );
        },

        /** @private */
        ValueIterator: qx.Class.define( 'jsava.util.HashMap.ValueIterator', {
            extend: jsava.util.HashMap.HashIterator,

            construct: function (thisHashMap) {
                this.base( arguments, thisHashMap );
            },

            members: {
                next: function () {
                    return this._nextEntry()._value;
                }
            }
        } ),

        /** @private */
        KeyIterator: qx.Class.define( 'jsava.util.HashMap.KeyIterator', {
            extend: jsava.util.HashMap.HashIterator,

            construct: function (thisHashMap) {
                this.base( arguments, thisHashMap );
            },

            members: {
                next: function () {
                    return this._nextEntry().getKey();
                }
            }
        } ),

        /** @private */
        EntryIterator: qx.Class.define( 'jsava.util.HashMap.EntryIterator', {
            extend: jsava.util.HashMap.HashIterator,

            construct: function (thisHashMap) {
                this.base( arguments, thisHashMap );
            },

            members: {
                next: function () {
                    return this._nextEntry();
                }
            }
        } ),

        /** @private */
        KeySet: qx.Class.define( 'jsava.util.HashMap.KeySet', {
            extend: jsava.util.AbstractSet,

            construct: function (thisHashMap) {
                this.base( arguments );
                this.__thisHashMap = thisHashMap;
            },

            members: {
                __thisHashMap: null,

                iterator: function () {
                    return this.__thisHashMap._newKeyIterator();
                },

                size: function () {
                    return this.__thisHashMap._size;
                },

                contains: function (obj) {
                    return this.__thisHashMap.containsKey( obj );
                },

                remove: function (obj) {
                    return this.__thisHashMap._removeEntryForKey( obj ) !== null;
                },

                clear: function () {
                    this.__thisHashMap.clear();
                }
            }
        } ),

        /** @private */
        Values: qx.Class.define( 'jsava.util.HashMap.Values', {
            extend: jsava.util.AbstractCollection,

            construct: function (thisHashMap) {
                this.base( arguments );
                this.__thisHashMap = thisHashMap;
            },

            members: {
                __thisHashMap: null,

                iterator: function () {
                    return this.__thisHashMap._newValueIterator();
                },

                size: function () {
                    return this.__thisHashMap._size;
                },

                contains: function (obj) {
                    return this.__thisHashMap.containsValue( obj );
                },

                clear: function () {
                    this.__thisHashMap.clear();
                }
            }
        } ),

        /** @private */
        EntrySet: qx.Class.define( 'jsava.util.HashMap.EntrySet', {
            extend: jsava.util.AbstractSet,

            construct: function (thisHashMap) {
                this.base( arguments );
                this.__thisHashMap = thisHashMap;
            },

            members: {
                __thisHashMap: null,

                iterator: function () {
                    return this.__thisHashMap._newEntryIterator();
                },

                size: function () {
                    return this.__thisHashMap._size;
                },

                contains: function (obj) {
                    if( obj === null || !qx.Class.implementsInterface( obj, jsava.util.Map.Entry ) ) {
                        return false;
                    }

                    /** @implements jsava.util.Map.Entry */
                    var entry = obj,
                        candidate = this.__thisHashMap._getEntry( entry.getKey() );
                    return candidate !== null && candidate.equals( entry );
                },

                remove: function (obj) {
                    return this.__thisHashMap._removeMapping( obj ) !== null;
                },

                clear: function () {
                    this.__thisHashMap.clear();
                }
            }
        } )
    }
} );

হুম আকর্ষণীয় পদ্ধতির .. আপনি কি একটি স্বয়ংক্রিয় পদ্ধতির চেষ্টা বিবেচনা করেছেন? তা হল, বর্তমান জাভা বাস্তবায়নের জন্য উত্স কোডে জাভা-থেকে-জাভাস্ক্রিপ্ট সংকলক চলছে?
ক্লাদিউ

নাহ :) এটি আমার জন্য একটি মজাদার প্রকল্প এবং আমি খুব সহজেই "অনুলিপি" কোডটি পারতাম না এমন বেশ কয়েকটি জিনিস ছিল। আমি জাভা-থেকে-জাভাস্ক্রিপ্ট সংকলক সম্পর্কে সচেতন নই, যদিও আমি বিশ্বাস করি যে সেগুলি বিদ্যমান। আমি নিশ্চিত নই যে তারা এটি কতটা ভাল অনুবাদ করবে। আমি মোটামুটি নিশ্চিত যে তারা কোনও অবস্থাতেই ভাল মানের কোড তৈরি করবে না।
ইনগো বার্ক

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

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

চারপাশে মজা করা শিখার সেরা উপায় =)। ভাগ করে নেওয়ার জন্য ধন্যবাদ
ক্লাদিউ

0

তবুও আমার দ্বারা অন্য একটি মানচিত্র বাস্তবায়ন। র্যান্ডমাইজার, 'জেনেরিক্স' এবং 'পুনরায়' দিয়ে) =)

var HashMap = function (TKey, TValue) {
    var db = [];
    var keyType, valueType;

    (function () {
        keyType = TKey;
        valueType = TValue;
    })();

    var getIndexOfKey = function (key) {
        if (typeof key !== keyType)
            throw new Error('Type of key should be ' + keyType);
        for (var i = 0; i < db.length; i++) {
            if (db[i][0] == key)
                return i;
        }
        return -1;
    }

    this.add = function (key, value) {
        if (typeof key !== keyType) {
            throw new Error('Type of key should be ' + keyType);
        } else if (typeof value !== valueType) {
            throw new Error('Type of value should be ' + valueType);
        }
        var index = getIndexOfKey(key);
        if (index === -1)
            db.push([key, value]);
        else
            db[index][1] = value;
        return this;
    }

    this.get = function (key) {
        if (typeof key !== keyType || db.length === 0)
            return null;
        for (var i = 0; i < db.length; i++) {
            if (db[i][0] == key)
                return db[i][1];
        }
        return null;
    }

    this.size = function () {
        return db.length;
    }

    this.keys = function () {
        if (db.length === 0)
            return [];
        var result = [];
        for (var i = 0; i < db.length; i++) {
            result.push(db[i][0]);
        }
        return result;
    }

    this.values = function () {
        if (db.length === 0)
            return [];
        var result = [];
        for (var i = 0; i < db.length; i++) {
            result.push(db[i][1]);
        }
        return result;
    }

    this.randomize = function () {
        if (db.length === 0)
            return this;
        var currentIndex = db.length, temporaryValue, randomIndex;
        while (0 !== currentIndex) {
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex--;
            temporaryValue = db[currentIndex];
            db[currentIndex] = db[randomIndex];
            db[randomIndex] = temporaryValue;
        }
        return this;
    }

    this.iterate = function (callback) {
        if (db.length === 0)
            return false;
        for (var i = 0; i < db.length; i++) {
            callback(db[i][0], db[i][1]);
        }
        return true;
    }
}

উদাহরণ:

var a = new HashMap("string", "number");
a.add('test', 1132)
 .add('test14', 666)
 .add('1421test14', 12312666)
 .iterate(function (key, value) {console.log('a['+key+']='+value)});
/*
a[test]=1132
a[test14]=666
a[1421test14]=12312666 
*/
a.randomize();
/*
a[1421test14]=12312666
a[test]=1132
a[test14]=666
*/
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.