javascript العمليات - كيفية تخصيص مساواة الكائنات لمجموعة جافا سكريبت




الحسابية الجافا (5)

لا يحتوي كائن Set ES6 على أي طرق مقارنة أو مقارنة قابلة للتوسعة.

تعمل أساليب .add() و .add() و .delete() فقط من كونها نفس الكائن الفعلي أو القيمة نفسها .delete() وليس لديها وسيلة للتوصيل أو استبدال هذا المنطق.

يمكنك افتراضًا أن تشتق الكائن الخاص بك من Set واستبدال .add() ، و .add() و. .delete() الطرق مع شيء لم مقارنة كائن عميق أولا للعثور على ما إذا كان العنصر بالفعل في المجموعة ، ولكن الأداء من المحتمل ألا يكون جيدًا لأن كائن Set الأساسي لن يساعد على الإطلاق. قد تحتاج إلى القيام بتكرار استخدام brute force عبر كافة الكائنات الموجودة للعثور على تطابق باستخدام المقارنة المخصصة الخاصة بك قبل استدعاء. .add() الأصلي.

فيما يلي بعض المعلومات من هذه المقالة ومناقشة ميزات ES6:

5.2 لماذا لا يمكنني تكوين كيفية مقارنة الخرائط والمجموعات بالمفاتيح والقيم؟

سؤال: سيكون من الجميل إذا كان هناك طريقة لتكوين مفاتيح الخريطة وما هي عناصر المجموعة التي تعتبر متساوية. لماذا ليس هناك؟

الإجابة: تم تأجيل هذه الميزة ، حيث يصعب تنفيذها بشكل صحيح وكفء. يتمثل أحد الخيارات في تسليم الاستدعاءات إلى المجموعات التي تحدد المساواة.

هناك خيار آخر متاح في Java ، وهو تحديد المساواة عبر طريقة تقوم بتنفيذ الكائن (يساوي () في Java). ومع ذلك ، فإن هذا النهج يمثل مشكلة بالنسبة للأشياء القابلة للتغيير: بشكل عام ، إذا تغير كائن ما ، فإن "موقعه" داخل مجموعة يجب أن يتغير أيضًا. ولكن هذا ليس ما يحدث في جافا. ربما ستذهب لغة جافا سكريبت إلى المسار الأكثر أمانًا فقط من خلال تمكين المقارنة حسب القيمة للأشياء غير القابلة للتغيير (ما يطلق عليه كائنات القيمة). تعني المقارنة بالقيمة أن قيمتين تعتبر متساوية إذا كانت محتوياتها متساوية. تتم مقارنة القيم الأولية بالقيمة في JavaScript.

تقدم ES 6 الجديدة (الوئام) كائن Set جديدة. تشبه خوارزمية الهوية المستخدمة بواسطة Set المشغل === وبالتالي فهي غير مناسبة لمقارنة الأشياء:

var set = new Set();
set.add({a:1});
set.add({a:1});
console.log([...set.values()]); // Array [ Object, Object ]

كيفية تخصيص المساواة لكائنات مجموعة من أجل القيام بمقارنة الأشياء العميقة؟ هل هناك أي شيء مثل جافا equals(Object) ؟


ربما يمكنك محاولة استخدام JSON.stringify() للقيام بمقارنة الأشياء العميقة.

فمثلا :

const arr = [
  {name:'a', value:10},
  {name:'a', value:20},
  {name:'a', value:20},
  {name:'b', value:30},
  {name:'b', value:40},
  {name:'b', value:40}
];

const names = new Set();
const result = arr.filter(item => !names.has(JSON.stringify(item)) ? names.add(JSON.stringify(item)) : false);

console.log(result);


للإضافة إلى الإجابات هنا ، تقدمت إلى الأمام وقمت بتنفيذ برنامج إغلاق الخريطة الذي يأخذ وظيفة هاش مخصصة ، ووظيفة مساواة مخصصة ، ويخزن القيم المتميزة التي لها تجاويف (مخصصة) مكافئة في المجموعات.

بشكل متوقع ، تبين أنها أبطأ من طريقة تسلسل سلسلة czerny .

المصدر الكامل هنا: https://github.com/makoConstruct/ValueMap


كما هو مذكور في إجابة jfriend00 ، قد لا يكون تخصيص علاقة المساواة ممكنًا .

تقدم التعليمة البرمجية التالية مخطط تفصيلي للمشكلة حسابياً (ولكن تكلفة الذاكرة):

class GeneralSet {

    constructor() {
        this.map = new Map();
        this[Symbol.iterator] = this.values;
    }

    add(item) {
        this.map.set(item.toIdString(), item);
    }

    values() {
        return this.map.values();
    }

    // ...
}

يجب على كل عنصر مدرج تنفيذ الأسلوب toIdString() الذي يقوم بإرجاع السلسلة. تعتبر كائنين متساوية إذا وفقط إذا كانت أساليب toIdString الخاصة بها toIdString بإرجاع نفس القيمة.


استعمال:

// window.location
window.location.replace('http://www.example.com')
window.location.assign('http://www.example.com')
window.location.href = 'http://www.example.com'
document.location.href = '/path'

// window.history
window.history.back()
window.history.go(-1)

// window.navigate; ONLY for old versions of Internet Explorer
window.navigate('top.jsp')


// Probably no bueno
self.location = 'http://www.example.com';
top.location = 'http://www.example.com';

// jQuery
$(location).attr('href','http://www.example.com')
$(window).attr('location','http://www.example.com')
$(location).prop('href', 'http://www.example.com')




javascript set ecmascript-harmony