在某个属性中重复检查javascript对象列表

时间:2014-06-09 04:55:19

标签: javascript jquery

我有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中的任何类型的列表创建可以检查重复项的通用方法?

3 个答案:

答案 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的对象!!