简体   繁体   English

如何确保类型检查 function 返回相同 arguments 的相同引用

[英]How to ensure type check a function returns the same reference for same arguments

I have a bunch of functions that combines each other to return new objects.我有一堆相互结合以返回新对象的函数。 Some functions return sets composed of return values of these other functions.一些函数返回由这些其他函数的返回值组成的集合。 I want to get the same object reference out of these functions for same arguments, so the set doesn't contain duplicates.我想从这些函数中为相同的 arguments 获得相同的 object 参考,因此该集合不包含重复项。

type A = { a: number, b: number };

type A2 = { c: A, d: A };

function makeA(a: number, b: number): A {
    return {
        a, b
    };
}

function makeA2(c: A, d: A): A2 {
    return { c, d };
}

console.log(makeA(2, 3) === makeA(2, 3)); // I want this to be true

let res = [
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2)),
makeA2(makeA(1,1), makeA(1,2))
];

console.log(new Set(res)); // so I get a single element in this list

I've tried building a utility function called DB that keeps a map the two arguments that the functions take to the return value of the function, and on second call return from the cached value, but I am still getting duplicates, I think I am missing to wrap some functions, or there is a fundamental flaw in my logic. I've tried building a utility function called DB that keeps a map the two arguments that the functions take to the return value of the function, and on second call return from the cached value, but I am still getting duplicates, I think I am缺少包装一些功能,或者我的逻辑存在根本缺陷。

Yes, you would need to cache the return values of makeA and makeA2 so that the same inputs result in the same outputs.是的,您需要缓存makeAmakeA2的返回值,以便相同的输入产生相同的输出。 There are a number of ways to do this, but the important thing is to make sure that you are identifying "the same inputs" in robust way.有很多方法可以做到这一点,但重要的是确保您以稳健的方式识别“相同的输入”。

Here's one possible implementation, which maintains a separate cache for each function.这是一种可能的实现,它为每个 function 维护一个单独的缓存。 There's some code duplication here, so there's an opportunity to streamline it, but the point is to show something that works:这里有一些代码重复,所以有机会简化它,但重点是展示一些有效的东西:

function makeA(a: number, b: number): A {
    const key = a + ";" + b;
    let ret = makeA.cache.get(key);
    if (!ret) {
        ret = { a, b };
        makeA.cache.set(key, ret);
    }
    return ret;
}
makeA.cache = new Map<string, A>();

function makeA2(c: A, d: A): A2 {
    const key = c.a + ";" + c.b + ";" + d.a + ";" + d.b;
    let ret = makeA2.cache.get(key);
    if (!ret) {
        ret = { c, d };
        makeA2.cache.set(key, ret);
    }
    return ret;
}
makeA2.cache = new Map<string, A2>();

For makeA , the "same inputs" are determined by concatenating the string representation of the two numeric inputs with a semicolon between them to get a string -valued lookup key.对于makeA ,“相同的输入”是通过将两个数字输入的字符串表示形式与它们之间的分号连接起来来确定的,以获得string值的查找键。 For makeB , I'm doing this with the four individual numeric subproperties.对于makeB ,我使用四个单独的数字子属性来执行此操作。 Technically, you should only need to use the "identities" of the c and d objects, but doing this is more tedious (you might end up maintaining a Map<A, Map<A, A2>> instance which is ) and doesn't necessarily buy you much.从技术上讲,您应该只需要使用cd对象的“身份”,但是这样做会更加乏味(您最终可能会维护一个Map<A, Map<A, A2>>实例)并且没有不一定给你买太多。 If someone calls makeA2({a: 1, b: 2}, {a: 1, b: 2}) with object literals, do you want the result to be different from if someone calls it like const a = {a:1, b:2}; makeA2(a, a)如果有人用 object 文字调用makeA2({a: 1, b: 2}, {a: 1, b: 2}) ,您是否希望结果与有人像const a = {a:1, b:2}; makeA2(a, a) const a = {a:1, b:2}; makeA2(a, a) ? const a = {a:1, b:2}; makeA2(a, a) Probably not, if your goal is not to proliferate instances.如果您的目标不是增加实例,可能不会。

In each case we look up the key in the cache;在每种情况下,我们都会在缓存中查找键; if it's there, great.如果它在那里,那就太好了。 If not, we create the entry at that key and return that.如果没有,我们在该键处创建条目并返回它。


Let's see if it works:让我们看看它是否有效:

console.log(makeA(2, 3) === makeA(2, 3)); // true

let res = [
    makeA2(makeA(1, 1), makeA(1, 2)),
    makeA2(makeA(1, 1), makeA(1, 2)),
    makeA2(makeA(1, 1), makeA(1, 2)),
    makeA2(makeA(1, 1), makeA(1, 2))
];

console.log(new Set(res).size); // 1

Looks good.看起来不错。

Playground link to code Playground 代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何记忆函数以便从缓存返回相同的参数 - How to memoize function so same arguments returns from cache 确保我的函数返回变异对象作为同一个类打字稿的实例? - Ensure my function returns mutated object as instanceof the same class typescript? 如何使用Flow泛型使用相同类型的参数制作泛型函数 - How to make a generic function with the arguments of the same type using Flow generics TypeScript 相同 function arguments 类型不同的实现 - TypeScript same function arguments type with different implementation 如何在给定相同的 arguments 的情况下获得相同的参考以进行相等性测试 - How to get the same reference given same arguments for equality test 在函数的@param和@returns中使用相同的泛型类型 - Use of same generic type in @param and @returns for a function 如何检查两个变量是否具有相同的引用? - How to check if two vars have the same reference? 如何使用相同的功能检查`toHaveBeenCalledWith` - How to check `toHaveBeenCalledWith` with same function 如果传递了相同的 arguments,如何防止 function 调用? - How to prevent a function call if the same arguments are passed? 如何检查所有参数是否都相同并返回字符串 - How to check if all arguments equal the same thing and return a string
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM