Javascript 避免密钥/数据重复

Javascript 避免密钥/数据重复,javascript,Javascript,我对JS中的一些现有代码有一个设计上的烦恼。代码正在运行,所以我并不急于修改它,但下面显示的重复确实让我很恼火。避免这种情况的通常/推荐/官方方式是什么 实际系统是一个大型/复杂的金融系统,因此我将其简化为最基本的示例,以说明问题: var colours={ red:{id:"red", vals:[1,0,0]}, green:{id:"green", vals:[0,1,0]}, grey:{id:"grey", vals:[0.5,0.5,0.5]}

我对JS中的一些现有代码有一个设计上的烦恼。代码正在运行,所以我并不急于修改它,但下面显示的重复确实让我很恼火。避免这种情况的通常/推荐/官方方式是什么

实际系统是一个大型/复杂的金融系统,因此我将其简化为最基本的示例,以说明问题:

var colours={
     red:{id:"red", vals:[1,0,0]},
       green:{id:"green", vals:[0,1,0]},
       grey:{id:"grey", vals:[0.5,0.5,0.5]}
 // ...etc
    };

// id needs to be known internally within the object - thus it is defined as a property.
// e.g:
colour.prototype.identify(console.log(this.id));

// id also needs to be used externally to find an object quickly.
// e.g:
function getcolour(s){return colours[s];}

// Although this works. It does mean duplicating data, with the theoretical possibility of a mismatch:
var colours={//...
      blue:{id:"green", // oh dear...

专家们通常会如何处理这个问题?

我不会用其他方法直接更改颜色[key]以避免重复。 任何其他尝试都将导致处理,并且您已经提到您拥有大量数据

我假设复制是在传入数据之上的,这是一种浪费。 通过网络处理数据的一个例子是,遍历map对象并根据密钥动态设置id。(处理与流量)


这个问题有点主观

创建应用程序时,我通常会尝试执行以下操作:

  • 切勿在多个位置定义相同的数据。来源应始终明确无误
  • 如果我需要创建任何索引以更快/更容易地访问,我会使用实用工具方法来实现。这些方法应该经过适当的单元测试,这样我就不会怀疑它们做了错误的事情
  • 尽可能多地使用第三方库(如已经建议的lodash或下划线),以最大限度地减少要编写/维护的代码量
如果您的算法和实用程序经过适当的单元测试,您就不必担心(太多)数据会进入不一致的状态。但是,如果这些是非常重要的系统/接口,您可以在输出上添加一些验证。通常,对输入进行数据验证和封送处理是一种良好的做法

实用方法说明: 如果你有数据数组,比如

var data = [{"id":"i_1", ...}, {"id":"i_2", ...},{"id":"i_3",....}];
然后,你必须从中创建一个索引,或者基于原始数组创建更多的数据集,然后你自己创建一个实用方法库,对数组进行修改,创建派生数据集,或者对数组进行迭代,并动态创建结果项。例如:

var createIndex = function( arr ){
    // do something that converts the data array with expected structure to object
    // { 
    //     i_1: {"id":"i_1", ...},
    //     i_2: {"id":"i_2", ...},
    //     i_3: {"id":"i_3", ...}
    return newObj;
}

此方法将创建一个哈希映射来访问数据,这比始终在原始数组上迭代更快。但是现在,这种方法可以很容易地进行单元测试,并确保在源数据上使用它来获得预期的数据集时,不会出现不一致性

您可以过滤对象,将其转换为对象数组,然后过滤唯一值。将其转换为阵列将使您能够更快、更轻松地执行许多操作

因此,您可以将对象映射到阵列:

var coloursArray = myObj.map(function(value, index) {
    return [value];
});
删除重复项:

function removeDuplicates() {
    return coloursArray.filter((obj, pos, arr) => {
        return arr.map(mapObj => mapObj[id]).indexOf(obj[id]) === pos;
    });
}
您可以通过
.uniq方法
,例如使用下划线.js从数组中删除重复项:

var uniqueColoursArray = _.uniq(coloursArray , function(c){ return c.id; });
此外,此函数非常无用,因为您可以直接访问元素:

function getcolour(s){return colours[s];}
调用
colors[s]
它也比
getcolor(s)
短。如果您同时传递数组,那么您的函数是有意义的,因为它在其他一些作用域中是不可访问的

那么我不明白为什么要在这里传递console.log作为参数:

colour.prototype.identify(console.log(this.id));

也许你只想通过
this.id

看看图书馆同意第1点-这就是我问这个问题的全部原因。您能否详细说明“实用方法”如何比颜色更快地访问。“我不明白你的思路。”理查德在回答中补充道:“如果问题不够清楚,请原谅我。”。没有重复的对象-代码工作正常。复制是指密钥存储两次的面,因此(理论上)可能不一致。没有需要修复的实际错误-我只是在寻找避免这种不雅设计的技巧。我明白,但是数据是否像您描述的那样来自服务器?如果是这样的话,我试图解释为什么有时候你想要坚持你的解决方案,而不是改变它,因为其他解决方案,比如某人在这里给出的解决方案,将是一个需要时间的过程,特别是当它涉及大数据时。我给你的例子将添加处理并删除一些不必要的重复数据,你可以在客户端中处理这些数据-重复我指的是绿色:{vals:[0,1,0]}而不是绿色:{id:“green”,vals:[0,1,0]}较小的数据流量我担心我没有足够清楚地解释这个问题。我没有试图从数组中删除重复的元素。我担心数据(id)通过存储在两个不同的位置来复制:作为封闭对象中的键和作为子对象的属性。我只是想知道是否有一个聪明的设计方法,我忽略了这将避免这一点。是的,这是不清楚。只需以这种方式更改您的设计:
var colors=[{id:“red”,vals:[1,0,0]},{id:“green”,vals:[0,1,0]},{id:“grey”,vals:[0.5,0.5,0.5]}
colour.prototype.identify(console.log(this.id));