typescript - Bir nesneyi kendi özelliğine eşlemek kötü bir uygulama mıdır?


Kendimi sık sık, kimlik numaraları veya onları tanımlayan isimleri olan, ancak aynı zamanda nesnenin bir özelliği olan nesneleri dolaştırırken buluyorum. Örneğin:

type ExampleItemName = string;
interface ExampleItem {
  name: ExampleItemName ;
  value: number;
}

Ben de sık sık bu öğelerin listelerini oluşturmak zorunda kalıyorum ve öğelere name ile erişebilmenin kullanışlı olduğunu düşünüyorum. Bunun için görebildiğim en mantıklı veri yapısı bir Map, yani:

type ExampleItemList = Map<ExampleItemName, ExampleItem>;

Bu kullanışlı ve pratiktir, çünkü Map.get ile herhangi bir öğeye name ile erişebilirim, ama aynı zamanda bütün listeyi for...of kullanarak kolayca yineleyebilirim.

Ancak bu bana yanlış geliyor çünkü name bilgisi çoğaltılmış durumda - hem haritanın anahtarında hem de değerinde mevcut. Eğer bir ExampleItem’in namei değişirse, haritadaki karşılık gelen anahtar değişmiyor, bu yüzden kırılgan hissettiriyor.

Bu kötü bir uygulama mı? Öyleyse, aradığım işlevselliği elde etmenin daha iyi bir yolu nedir?

Cevap #1

Bu kendi başına kötü bir uygulama değildir, ancak belirli bazı koşulların karşılanması gerekir, aksi takdirde, değiştirdiğiniz değerle anahtar oluşturduğunuzda bahsettiğiniz gibi sorunlarla karşılaşırsınız. Bu desen genellikle verilerinizi anahtarlama eylemi olarak adlandırılır. Verilerinizi, değişmeyeceğini bildiğiniz değerlerle, örneğin bir ID ile anahtarlamak en iyi uygulamadır. Sözlükler genellikle pahalı arama işlevlerinin maliyetini düşürebildiğinden birçok durumda gereklidir, ancak belirttiğim gibi ve sizin de işaret ettiğiniz gibi, ya onları değişmeyecek ve benzersiz bir değerle anahtarlamalısınız ya da her sözlüğü kullandığınızda güncellemeli ve kopyaları yönetmelisiniz. Hangi çözümün gerekli olduğu duruma bağlıdır.

Ayrıca, lodash gibi kütüphanelerin, verileri alıp sizin için anahtarlandıran yerleşik fonksiyonları vardır (bunları kendiniz de kolayca yazabilirsiniz). Bu tür fikirlerin, farklı adlarla anılsalar bile (python: dictionary, Java: hashMap, vb.) diğer dillerde de yaygın olarak kullanıldığını göreceksiniz.

Cevap #2

Eğer çok zahmetli değilse, kullanım durumunuzu karşılayan kendi liste yapınızı oluşturmaya çalışabilirsiniz, örneğin aşağıdaki gibi.

class NameMap<K, V extends { name: K }> {
    private items: Set<V> = new Set();
    Add(value: V) { this.items.add(value); }
    Get(key: K) {
        for(let e of this.items.values()) if(e.name == key) return e;
        return undefined;
    }
    [Symbol.iterator]() { return this.items[Symbol.iterator](); };
}

type ExampleItemList = NameMap<ExampleItemName, ExampleItem>;