对象数组的无副本版本

时间:2015-07-23 16:32:21

标签: javascript arrays object

我实现了一个创建数组的无副本版本的函数,但它不适用于对象数组。我不明白,我无法找到解决问题的方法。

我的功能:

function uniq(array) {
    var length = array.length;

    if (!length) {
        return;
    }

    var index = 0;
    var result = [];

    while (index < length) {
        var current = array[index];
        if (result.indexOf(current) < 0) {
            result.push(current);
        }
        index++;
    }

    return result;
}

示例:

var my_data = [    
    {
        "first_name":"Bob",
        "last_name":"Napkin"
    },
    {   
        "first_name":"Billy",
        "last_name":"Joe"
    }, 
    {
        "first_name":"Billy",
        "last_name":"Joe",
    }
]

uniq([1, 1, 2, 3]) // => [1, 2, 3]

uniq(my_data) // => [ { "first_name":"Bob", "last_name":"Napkin" }, { "first_name":"Billy", "last_name":"Joe" }, { "first_name":"Billy", "last_name":"Joe" } ]

您是否知道如何创建对象数组的无副本版本?

3 个答案:

答案 0 :(得分:1)

javascript中的indexOf()不执行对象的深度比较。最重要的是,创建的任何两个对象永远不会是#34;相等&#34;对彼此。如果你这样做:

var a = {};
var b = {};
a == b; //false
a === b; //false

您需要针对所有值执行深度比较(如果这甚至是您正在寻找的事情,因为您可能还有其他的等同性对于)。我不知道如何进行深入的比较,因为谷歌。

答案 1 :(得分:1)

一个解决方案,如果对象不是很大,数组没有大量的元素,如果对象不包含引用循环,则使用JSON.stringify来决定是否有两个对象是平等的......

function uniq(A) {
    var seen = {};
    var result = [];
    A.forEach(function(x) {
        var str = "" + JSON.stringify(x);
        if (!seen[str]) {
            seen[str] = 1;
            result.push(x);
        }
    });
    return result;
}

答案 2 :(得分:1)

由于这些对象仅用于数据存储(即它们没有方法或原型扩展并且应用于它们),我可能建议对数组中的每个对象进行序列化和散列,并将散列存储在对象中以供确定独特性现在问题是要使用哪种散列函数。有许多可用的md5和SHA-256实现(为此搜索StackOverflow)。我的例子将假设存在一个名为hashFunction()的哈希函数。

function uniqArrayObjects(array) {
    // make sure we have an array
    if(Array.isArray(array) === false) {
         console.log('Doh! No array passed.');
         return null;
    }

    var length = array.length;
    // you can return input array if it has 0 or 1 items in it
    // it is already unique
    if (length === 0 || length === 1) {
       return array;
    }

    // object for storing hashes
    var hashTable = {};

    // filter and return the array
    return array.filter(function(obj) {
        var json = JSON.stringify(obj);
        var hash = hashFunction(json);
        if (typeof hashTable[hash] === undefined) {
           // this item doesn't exist in hash table yet
           // add to hash table and return true to add this to filtered result
           hashTable[hash] = 1; // value doesn't matter here
           return true;
        } else {
           return false;
        }
    });
}