সমতা জন্য ECMA6 সেট তুলনা


107

আপনি দুটি জাভাস্ক্রিপ্ট সেট কীভাবে তুলনা করবেন? আমি ব্যবহার করার চেষ্টা করেছি ==এবং ===উভয়ই মিথ্যা প্রত্যাবর্তন করেছি।

a = new Set([1,2,3]);
b = new Set([1,3,2]);
a == b; //=> false
a === b; //=> false

এই দুটি সেট সমতুল্য, কারণ সংজ্ঞা অনুসারে, সেটের অর্ডার নেই (অন্তত সাধারণত নয়)। আমি সেট অন এমডিএন এর জন্য ডকুমেন্টেশনগুলি দেখেছি এবং দরকারী কিছুই পাই নি। কেউ কি করতে পারে জানেন?


দুটি সেট দুটি পৃথক বস্তু। ===মান সমতা জন্য নয়, সমতা অবজেক্ট।
elclanrs

4
পুনরাবৃত্তি করুন এবং প্রতিটি সদস্যের মান তুলনা করুন, যদি সব একই হয় তবে সেটটি "একই"
ডান্ডাভিস

4
@dandavis সেট সঙ্গে, সদস্য হয় মান।

4
সেট এবং মানচিত্রের একটি অর্ডার রয়েছে, যা সন্নিবেশ আদেশ - যে কোনও কারণেই: বিকাশকারী.মোজিলা.আর.ইন-
ইউএস

10
সবচেয়ে খারাপ, এমনকি new Set([1,2,3]) != new Set([1,2,3])। এটি জাভাস্ক্রিপ্ট সেট সেটগুলির জন্য অকেজো করে তোলে কারণ সুপারসেটে সদৃশ সাবলেট থাকবে contain একমাত্র ওয়ার্কআরআন্ড যা মনে মনে আসে সমস্ত সাবটাকে অ্যারেতে রূপান্তরিত করে প্রতিটি অ্যারে বাছাই করে এবং তারপরে প্রতিটি অ্যারে স্ট্রিং হিসাবে এনকোড করা হয় (উদাহরণস্বরূপ জেএসওএন)।
7vujy0f0hy

উত্তর:


79

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

var a = new Set([1,2,3]);
var b = new Set([1,3,2]);

alert(eqSet(a, b)); // true

function eqSet(as, bs) {
    if (as.size !== bs.size) return false;
    for (var a of as) if (!bs.has(a)) return false;
    return true;
}

আরও কার্যকরী পদ্ধতি হ'ল:

var a = new Set([1,2,3]);
var b = new Set([1,3,2]);

alert(eqSet(a, b)); // true

function eqSet(as, bs) {
    return as.size === bs.size && all(isIn(bs), as);
}

function all(pred, as) {
    for (var a of as) if (!pred(a)) return false;
    return true;
}

function isIn(as) {
    return function (a) {
        return as.has(a);
    };
}

allফাংশন সব iterable বস্তু (যেমন জন্য কাজ করে Setএবং Map)।

যদি Array.fromআরও ব্যাপকভাবে সমর্থিত হয় তবে আমরা allফাংশনটি এইভাবে প্রয়োগ করতে পারতাম :

function all(pred, as) {
    return Array.from(as).every(pred);
}

আশা করি এইটি কাজ করবে.


4
আমার মনে হয় আপনি নাম পরিবর্তন করা উচিত hasকরতে isPartOfবা isInঅথবাelem
Bergi

@Bergi আমি ফাংশনের নাম পরিবর্তন hasকরতে isIn
অদিত এম শাহ

4
@ ডেভিডগিভেন হ্যাঁ, জাভাস্ক্রিপ্টে সেটগুলি সন্নিবেশ ক্রমে পুনরাবৃত্তি করা হয়: বিকাশকারী.মোজিলা.আর.ইন-
ইউএস / ডকস / ওয়েবে / জাভা স্ক্রিপ্ট / রেফারেন্স /

56
প্রতিদিন আমি জাভাস্ক্রিপ্টে সর্বাধিক স্বল্প ভাষা তৈরির বিষয়ে আরও নিশ্চিত assured এর সীমাবদ্ধতা মোকাবেলার জন্য প্রত্যেককেই তাদের নিজস্ব বুনিয়াদি কাজগুলি আবিষ্কার করতে হবে এবং এটি ES6 এ রয়েছে এবং আমরা 2017 সালে আছি! কেন তারা সেট অবজেক্টের স্পেসিফিকেশনে এ জাতীয় ঘন ফাংশন যুক্ত করতে পারেনি!
ঘাসন

4
@ ঘাসানআল-সাক্কাফ, আমি একমত, এটি হতে পারে যে
টিসি 39

68

আপনিও চেষ্টা করতে পারেন:

var a = new Set([1,2,3]);
var b = new Set([1,3,2]);

isSetsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value));

console.log(isSetsEqual(a,b)) 


এটি যদি একটি শর্তের মধ্যে ফিট করে তবে অবশ্যই এটি আরও ভাল সমাধান
হুগডবি

আমি এই সমাধানটি কতটা মূর্খবাদী, এবং কতটা পাঠযোগ্য! ধন্যবাদ @ ম্যাক্স
ডেডিমায়ার

32

লডাশ সরবরাহ করে _.isEqual(), যা গভীর তুলনা করে। আপনি নিজের লেখাতে না চাইলে এটি খুব সহজ। লোটাস 4 হিসাবে, _.isEqual()সঠিকভাবে সেটগুলির সাথে তুলনা করা হয়।

const _ = require("lodash");

let s1 = new Set([1,2,3]);
let s2 = new Set([1,2,3]);
let s3 = new Set([2,3,4]);

console.log(_.isEqual(s1, s2)); // true
console.log(_.isEqual(s1, s3)); // false

7

অন্য উত্তর ভাল কাজ করবে; এখানে অন্য বিকল্প।

// Create function to check if an element is in a specified set.
function isIn(s)          { return elt => s.has(elt); }

// Check if one set contains another (all members of s2 are in s1).
function contains(s1, s2) { return [...s2] . every(isIn(s1)); }

// Set equality: a contains b, and b contains a
function eqSet(a, b)      { return contains(a, b) && contains(b, a); }

// Alternative, check size first
function eqSet(a, b)      { return a.size === b.size && contains(a, b); }

তবে, সচেতন থাকুন যে এটি গভীর সমতার তুলনা করে না । তাই

eqSet(Set([{ a: 1 }], Set([{ a: 1 }])

মিথ্যা ফিরে আসবে। উপরের দুটি সেটকে যদি সমান হিসাবে বিবেচনা করা হয় তবে প্রতিটি উপাদানকে গভীর মানের তুলনা করে আমাদের দুটি সেট দিয়ে পুনরাবৃত্তি করতে হবে। আমরা একটি deepEqualরুটিনের অস্তিত্বকে স্থির করি । তাহলে যুক্তি হবে

// Find a member in "s" deeply equal to some value
function findDeepEqual(s, v) { return [...s] . find(m => deepEqual(v, m)); }

// See if sets s1 and s1 are deeply equal. DESTROYS s2.
function eqSetDeep(s1, s2) {
  return [...s1] . every(a1 => {
    var m1 = findDeepEqual(s2, a1);
    if (m1) { s2.delete(m1); return true; }
  }) && !s2.size;
}

এটি কী করে: এস 1 এর প্রতিটি সদস্যের জন্য, s2 এর গভীর সমান সদস্যের সন্ধান করুন। যদি পাওয়া যায়, এটি মুছুন যাতে এটি আর ব্যবহার করা যায় না। দুটি সেট গভীরভাবে সমান যদি S1 মধ্যে সব উপাদান S2 পাওয়া যায়, এবং S2 ক্লান্ত হয়। নিরীক্ষিত।

আপনি এটি দরকারী খুঁজে পেতে পারেন: http://www.2ality.com/2015/01/es6-set-operations.html


7

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

সমাধান

var toJsonSet = aset /* array or set */ => JSON.stringify([...new Set(aset)].sort()); 
var fromJsonSet = jset => new Set(JSON.parse(jset));

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

var toJsonSet = aset /* array or set */ => JSON.stringify([...new Set(aset)].sort()); 
var fromJsonSet = jset => new Set(JSON.parse(jset));

var [s1,s2] = [new Set([1,2,3]), new Set([3,2,1])];
var [js1,js2] = [toJsonSet([1,2,3]), toJsonSet([3,2,1])]; // even better

var r = document.querySelectorAll("td:nth-child(2)");
r[0].innerHTML = (toJsonSet(s1) === toJsonSet(s2)); // true
r[1].innerHTML = (toJsonSet(s1) == toJsonSet(s2)); // true, too
r[2].innerHTML = (js1 === js2); // true
r[3].innerHTML = (js1 == js2); // true, too

// Make it normal Set:
console.log(fromJsonSet(js1), fromJsonSet(js2)); // type is Set
<style>td:nth-child(2) {color: red;}</style>

<table>
<tr><td>toJsonSet(s1) === toJsonSet(s2)</td><td>...</td></tr>
<tr><td>toJsonSet(s1) == toJsonSet(s2)</td><td>...</td></tr>
<tr><td>js1 === js2</td><td>...</td></tr>
<tr><td>js1 == js2</td><td>...</td></tr>
</table>

চূড়ান্ত পরীক্ষা: সেট সেট

var toSet = arr => new Set(arr);
var toJsonSet = aset /* array or set */ => JSON.stringify([...new Set(aset)].sort()); 
var toJsonSet_WRONG = set => JSON.stringify([...set]); // no sorting!

var output = document.getElementsByTagName("code"); 
var superarray = [[1,2,3],[1,2,3],[3,2,1],[3,6,2],[4,5,6]];
var superset;

Experiment1:
    superset = toSet(superarray.map(toSet));
    output[0].innerHTML = superset.size; // incorrect: 5 unique subsets
Experiment2:
    superset = toSet([...superset].map(toJsonSet_WRONG));
    output[1].innerHTML = superset.size; // incorrect: 4 unique subsets
Experiment3:
    superset = toSet([...superset].map(toJsonSet));
    output[2].innerHTML = superset.size; // 3 unique subsets
Experiment4:
    superset = toSet(superarray.map(toJsonSet));
    output[3].innerHTML = superset.size; // 3 unique subsets
code {border: 1px solid #88f; background-color: #ddf; padding: 0 0.5em;}
<h3>Experiment 1</h3><p>Superset contains 3 unique subsets but Javascript sees <code>...</code>.<br>Let’s fix this... I’ll encode each subset as a string.</p>
<h3>Experiment 2</h3><p>Now Javascript sees <code>...</code> unique subsets.<br>Better! But still not perfect.<br>That’s because we didn’t sort each subset.<br>Let’s sort it out...</p>
<h3>Experiment 3</h3><p>Now Javascript sees <code>...</code> unique subsets. At long last!<br>Let’s try everything again from the beginning.</p>
<h3>Experiment 4</h3><p>Superset contains 3 unique subsets and Javascript sees <code>...</code>.<br><b>Bravo!</b></p>


4
দুর্দান্ত সমাধান! এবং যদি আপনি জানেন যে আপনার কাছে কেবল স্ট্রিং বা সংখ্যাগুলির একটি সেট রয়েছে, তবে এটি কেবল হয়ে যায়[...set1].sort().toString() === [...set2].sort().toString()

3

আপনার পদ্ধতির মিথ্যা প্রত্যাবর্তনের কারণ হ'ল আপনি দুটি পৃথক বস্তুর তুলনা করছেন (যদিও তারা একই বিষয়বস্তু পেয়েছেন), এইভাবে দুটি পৃথক বস্তুর তুলনা করা (রেফারেন্স নয়, তবে অবজেক্ট) সর্বদা আপনাকে মিথ্যা ফিরিয়ে দেয়।

নিম্নলিখিত পদ্ধতির দুটি সেটটিকে একটিতে মার্জ করে এবং নির্বোধের সাথে আকারের তুলনা করে। যদি এটি একই হয় তবে এটি একই:

const a1 = [1,2,3];
const a2 = [1,3,2];
const set1 = new Set(a1);
const set2 = new Set(a2);

const compareSet = new Set([...a1, ...a2]);
const isSetEqual = compareSet.size === set2.size && compareSet.size === set1.size;
console.log(isSetEqual);

উপরিভাগ : এটি খুব সহজ এবং সংক্ষিপ্ত। কোনও বাহ্যিক গ্রন্থাগার কেবল ভ্যানিলা জেএস নয়

ডাউনসাইড : মানগুলি কেবল পুনরাবৃত্তি করার চেয়ে এটি সম্ভবত ধীর হতে চলেছে এবং আপনার আরও স্থান প্রয়োজন।


1

==, === সাথে দুটি বস্তুর তুলনা করা

যখন ব্যবহার ==বা ===অপারেটর দুটি বস্তুর তুলনা করতে, আপনি সবসময় পাবেন false যদি না ঐ অবজেক্ট রেফারেন্স একই বস্তুর । উদাহরণ স্বরূপ:

var a = b = new Set([1,2,3]); // NOTE: b will become a global variable
a == b; // <-- true: a and b share the same object reference

অন্যথায়, == মিথ্যা হিসাবে সমান হয় যদিও বস্তুটিতে একই মান রয়েছে:

var a = new Set([1,2,3]);
var b = new Set([1,2,3]);
a == b; // <-- false: a and b are not referencing the same object

আপনাকে ম্যানুয়াল তুলনা বিবেচনা করতে হবে

ECMAScript 6 এ আপনি সেটগুলি আগে থেকে অ্যারেতে রূপান্তর করতে পারেন যাতে আপনি তাদের মধ্যে পার্থক্যটি চিহ্নিত করতে পারেন:

function setsEqual(a,b){
    if (a.size !== b.size)
        return false;
    let aa = Array.from(a); 
    let bb = Array.from(b);
    return aa.filter(function(i){return bb.indexOf(i)<0}).length==0;
}

দ্রষ্টব্য: Array.from মানক ECMAScript 6 টির মধ্যে একটি বৈশিষ্ট্য তবে এটি আধুনিক ব্রাউজারগুলিতে ব্যাপকভাবে সমর্থিত নয়। সামঞ্জস্যতা টেবিলটি এখানে চেক করুন: https://developer.mozilla.org/en-US/docs/Web/ জাভা স্ক্রিপ্ট / রেফারেন্স / গ্লোবাল_অবজেক্টস / অ্যারে / ফর্ম # ব্রোজার_কম্প্যাটিবিলিটি


4
এটি bযার মধ্যে নেই তাদের সদস্য সনাক্ত করতে ব্যর্থ হবে না a?

4
পছন্দ করুন সবচেয়ে ভালো উপায় কিনা তা পরীক্ষা করে সদস্যদের এড়িয়ে যেতে bহয় না aকিনা চেক করা হল a.size === b.size
এডিট এম শাহ

4
a.size === b.sizeপ্রয়োজনে স্বতন্ত্র উপাদানের তুলনা প্রথমে শর্ট সার্কিটে রাখুন ?

4
যদি আকারটি পৃথক হয় তবে সংজ্ঞা অনুসারে সেটগুলি সমান নয়, তাই প্রথমে সেই শর্তটি পরীক্ষা করা ভাল।

4
ভাল, এখানে অন্য ইস্যুটি সেটগুলির প্রকৃতি অনুসারে সেটগুলিতে hasঅপারেশনটি খুব দক্ষ হিসাবে নকশাকৃত করা হয়েছে, indexOfঅ্যারেতে অপারেশন থেকে আলাদা । অতএব, আপনার ফিল্টার ফাংশনটি হিসাবে এটি বুদ্ধিমান হবে return !b.has(i)। এটি bঅ্যারে রূপান্তর করার প্রয়োজনকেও দূর করবে eliminate


1

গৃহীত উত্তরের উপর ভিত্তি করে, সমর্থন ধরে নিয়ে Array.from, এখানে একটি লাইন রয়েছে:

function eqSet(a, b) {
    return a.size === b.size && Array.from(a).every(b.has.bind(b));
}

বা সত্যিকারের ওয়ান-লাইনার ধরে নেওয়া তীর ফাংশন এবং স্প্রেড অপারেটর: eqSet = (a,b) => a.size === b.size && [...a].every(b.has.bind(b))
জন হাফফার

1

যদি সেটগুলিতে কেবলমাত্র প্রাথমিক তথ্য প্রকার থাকে বা সেটগুলির অভ্যন্তরে অবজেক্টের সমতা থাকে তবে সহজ উপায় আছে

const isEqualSets = (set1, set2) => (set1.size === set2.size) && (set1.size === new Set([...set1, ...set2]).size);


0

আমি পরীক্ষাগুলিতে এই পদ্ধতির অনুসরণ করি:

let setA = new Set(arrayA);
let setB = new Set(arrayB);
let diff = new Set([...setA].filter(x => !setB.has(x)));
expect([...diff].length).toBe(0);

5
এক সেকেন্ড অপেক্ষা করুন ... এটি কেবল এটিকে পরীক্ষা করে যে A তে এমন উপাদান রয়েছে যা বি তে নেই? এটিকে বি তে এমন উপাদান রয়েছে কিনা তা পরীক্ষা করে না। যদি আপনি চেষ্টা করেন a=[1,2,3]এবং b=[1,2,3,4], তবে তা বলে যে তারা একই। সুতরাং আমি অনুমান করি যে আপনার অতিরিক্ত চেক যেমনsetA.size === setB.size

0

@ অদিত এম শাহের উত্তরের ভিত্তিতে খুব সামান্য পরিবর্তন:

/**
 * check if two sets are equal in the sense that
 * they have a matching set of values.
 *
 * @param {Set} a 
 * @param {Set} b
 * @returns {Boolean} 
 */
const areSetsEqual = (a, b) => (
        (a.size === b.size) ? 
        [...a].every( value => b.has(value) ) : false
);

সাম্প্রতিকতম ব্যাবেলটির কারণে কিছুটা সমস্যা হওয়ায় আমি অন্য কারও কারও মতো সমস্যা থাকলে এখানে একটি স্পষ্ট শর্তযুক্ত যোগ করতে হয়েছিল।

(এছাড়াও areবহুবচনগুলির জন্য আমি মনে করি জোরে জোরে পড়ার জন্য আরও কিছুটা স্বজ্ঞাত 🙃)


0

সম্ভবত কিছুটা দেরি হলেও আমি সাধারণত নিম্নলিখিতগুলি করি:

const a = new Set([1,2,3]);
const b = new Set([1,3,2]);

// option 1
console.log(a.size === b.size && new Set([...a, ...b]).size === a.size)

// option 2
console.log([...a].sort().join() === [...b].sort().join())


-1

1) মাপ সমান কিনা তা পরীক্ষা করে দেখুন। যদি না হয় তবে তারা সমান নয়।

2) এ এর ​​প্রতিটি এলেমে পুনরাবৃত্তি করুন এবং বিতে উপস্থিত রয়েছে তা চেক করুন one unequal

3) উপরের 2 টি শর্ত যদি ব্যর্থ হয় তার অর্থ তারা সমান।

let isEql = (setA, setB) => {
  if (setA.size !== setB.size)
    return false;
  
  setA.forEach((val) => {
    if (!setB.has(val))
      return false;
  });
  return true;
}

let setA = new Set([1, 2, {
  3: 4
}]);
let setB = new Set([2, {
    3: 4
  },
  1
]);

console.log(isEql(setA, setB));

2) পদ্ধতি 2

let isEql = (A, B) => {
  return JSON.stringify([...A].sort()) == JSON.stringify([...B].sort());
}

let res = isEql(new Set([1, 2, {3:4}]), new Set([{3:4},1, 2]));
console.log(res);


এই উত্তরটি সম্পূর্ণ ভুল। forEachপদ্ধতিতে রিটার্নের বিবৃতি পিতামাতার ফাংশনটি ফেরত দেবে না।
xaviert
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.