我有javascript对象列表和像这样的对象
var student = function (config)
{
config = config || {}
this.id = config.id || 1;
this.Name = config.Name || "Shohel";
this.Roll = config.Roll || "04115407";
this.Session = config.Session || "03-04";
this.Subject = config.Subject || "CSE";
};
var students = [];
students.push(new student({ id: 2 }));
students.push(new student({ id: 3, Name: "Rana" }));
students.push(new student({ id: 4, Name: "Shipon" }));
students.push(new student({ id: 5, Name: "Pira" }));
现在我想推送另一个像这样的对象
students.push(new student({ id: 3, Name: "Rana" }));
它没有任何例外,但我想检查这个对象是否为
id是:3和名称:“Rana”
已经存在于学生列表中,我是否有太多的列表,如客户,产品,销售等。然后我无法对每个列表进行重复检查。这对我来说很麻烦。
如何为javascript中的任何类型的列表创建可以检查重复项的通用方法?
答案 0 :(得分:1)
这是可能的方法之一。可能它不是最有效的,但它确实很好。
Array.prototype.pushUnique = function (item) {
var newObj = JSON.stringify(item);
if (~(this.map(function (obj) { return JSON.stringify(obj); }).indexOf(newObj))) {
return false;
} else {
this.push(item);
return true;
}
}
使用pushUnique
方法将值推送到数组,并捕获像这样的例外
students.pushUnique(new student({id : 2}));
students.pushUnique(new student({id : 3, Name : "Rana"}));
students.pushUnique(new student({id : 2})); // This will throw an error
注意:强>
当您使用像以下
这样的普通JSON对象时,这将不起作用students.pushUnique({id : 2, Name: "Rana"});
students.pushUnique({Name: "Rana", id : 2});
由于对象键序列发生了变化,因此在字符串化时会产生不同的刺痛
编辑:(对于评论中提到的案例)
如果要检查特定键的单一性,则可以像这样修改函数。
Array.prototype.pushUnique = function (item, uniqueKeys) {
var newObj = {}, i , keyLen, arr, key;
if (!uniqueKeys) { uniqueKeys = Object.keys(item); } else if (!(uniqueKeys instanceof Array)) {
uniqueKeys = [uniqueKeys];
}
keyLen = uniqueKeys.length;
i = keyLen;
while (i--) { key = uniqueKeys[i]; newObj[key] = item[key]; }
newObj = JSON.stringify(newObj);
arr = this.map(function (obj) {
var obj_temp = {};
i = keyLen;
while (i--) { key = uniqueKeys[i]; obj_temp[key] = obj[key]; }
return JSON.stringify(obj_temp);
});
if (~arr.indexOf(newObj)) {
return false;
} else {
this.push(item);
return true;
}
}
并像
一样使用它students.pushUnique({Name: "Rana", id : 2}, ["id"]); // Pass keys in an array as second parameter
答案 1 :(得分:0)
你应该去Factory
概念。尝试这样的事情:
var _cache = {};
function recicleObject(type, options){
// Check if type already registered
if(!_cache[type])
_cache[type] = [];
// Check if ID is already taken
if(_cache[type][options.id]){
// Return the already made object
return _cache[type][options.id];
}else{
var obj = new window[type](options);
_cache[type][options.id] = obj;
return obj;
}
}
然后像这样使用它:
var newStudent = recicleObject('student', {id: ....});
答案 2 :(得分:0)
另一种解决方案是为学生ID保留另一个数组。 在推送每个元素之前,检查student id数组是否具有该id,如果没有条目,则继续。
您的修改后的代码将是,
var students = [];
var studentIds= [];
var student = function (config)
{
config = config || {}
this.id = config.id || 1;
this.Name = config.Name || "Shohel";
this.Roll = config.Roll || "04115407";
this.Session = config.Session || "03-04";
this.Subject = config.Subject || "CSE";
};
var pushStudentObj = function(studentObj){
if(!studentIds.contains(studentObj.id)){
students.push(studentObj);
}
}
并推送对象调用
pushStudentObj(new student({ id: 2 }));
pushStudentObj(new student({ id: 3, Name: "Rana" }));
pushStudentObj(new student({ id: 4, Name: "Shipon" }));
pushStudentObj(new student({ id: 5, Name: "Pira" }));
这将有效地推送具有新ID的对象!!