Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript删除对象数组中的重复对象&;对属性求和_Javascript_Arrays_Json - Fatal编程技术网

JavaScript删除对象数组中的重复对象&;对属性求和

JavaScript删除对象数组中的重复对象&;对属性求和,javascript,arrays,json,Javascript,Arrays,Json,几天来,我一直在试图找到解决问题的方法,但我无法想象我拥有以下JSON数组(我们称之为jsonData: [ { "id": 118748, "price":"", "stocklevel": 100, "instock": false, "pname": "Apple TV" }, { "id": 118805291, "price":"", "stocklevel": 432, "instock": true, "pname": "Hitachi TV"}, { "id"

几天来,我一直在试图找到解决问题的方法,但我无法想象我拥有以下JSON数组(我们称之为
jsonData

[
  { "id": 118748, "price":"", "stocklevel": 100,   "instock": false, "pname": "Apple TV" },
  { "id": 118805291, "price":"", "stocklevel": 432,   "instock": true, "pname": "Hitachi TV"},
  { "id": 118801891, "price":"", "stocklevel": 0,   "instock": false, "pname": "Sony TV" },
  { "id": 118748, "price":"", "stocklevel": 2345,   "instock": true, "pname": "Apple TV"},
...
现在,我的JSON数组中可能有100多个项目,我想删除具有重复id的项目,但求和库存水平并保留数组中的顺序,这样一行就应该取代该id的最新出现。在上面的JSON中,第一个具有“id”的对象实例:118748已删除,但它的库存级别值传递/添加了具有相同id的对象的下一个实例,因此JSON数组如下所示:

[
  { "id": 118805291, "price":"", "stocklevel": 432,   "instock": true, "pname": "Hitachi TV"},
  { "id": 118801891, "price":"", "stocklevel": 0,   "instock": false, "pname": "Sony TV" },
  { "id": 118748, "price":"", "stocklevel": 2445,   "instock": true, "pname": "Apple TV"},
...
我生成了以下代码来删除重复项,但我无法对库存总量求和,以下是我的代码:

function idsAreEqual(obj1, obj2) {
    return obj1.id === obj2.id;
}

function arrayContains(arr, val, equals) {
    var i = arr.length;
    while (i--) {
        if (equals(arr[i], val)) {
            return true;
        }
    }
    return false;
}

function removeDups(arr, equals) {
    var originalArr = arr.slice(0);
    var i, k, len, val;
    arr.length = 0;

    for (i = originalArr.length - 1, len = originalArr.length, k  = originalArr.length - 1 ; i > 0; --i) {
        val = originalArr[i];

        if (!arrayContains(arr, val, equals)) {
            arr.push(val);
        }
    }
}


removeDups(jsonData, idsAreEqual);
jsonData.reverse();
有人能帮我解决这个问题吗?请注意,我不能使用下划线、jQuery或任何其他库


提前非常感谢

您可以执行以下操作,这比我认为的实现要简单一些。我还使用了
forEach
reduce
,这两种浏览器都是ES5,但应该可以在现代浏览器上使用。如果您使用的是较旧的、不符合ES5的浏览器,您可以使用polyfil:

var data = [
  { "id": 118748, "price":"", "stocklevel": 0,   "instock": false, "pname": "Apple TV" },
  { "id": 118805291, "price":"", "stocklevel": 432,   "instock": true, "pname": "Hitachi TV"},
  { "id": 118801891, "price":"", "stocklevel": 0,   "instock": false, "pname": "Sony TV" },
  { "id": 118748, "price":"", "stocklevel": 2345,   "instock": true, "pname": "Apple TV"}
];

function dedup_and_sum(arr, prop) {
    var seen = {},
        order = [];
    arr.forEach(function(o) {
        var id = o[prop];
        if (id in seen) {
            // keep running sum of stocklevel
            var stocklevel = seen[id].stocklevel + o.stocklevel
            // keep this newest record's values
            seen[id] = o;  
            // upid[118805291], stocklevel=432, instock=truedate stocklevel to our running total
            seen[id].stocklevel = stocklevel;
            // keep track of ordering, having seen again, push to end
            order.push(order.splice(order.indexOf(id), 1));
        }
        else {
            seen[id] = o;
            order.push(id);
        }
    });

    return order.map(function(k) { return seen[k]; });
}

// Get unique records, keeping last record of dups
// and summing stocklevel as we go
var unique = dedup_and_sum(data, 'id');
unique.forEach(function(o) {
    console.log("id[%d], stocklevel=%d, instock=%s", o.id, o.stocklevel, o.instock);
});
// output =>
// id[118805291], stocklevel=432, instock=true
// id[118801891], stocklevel=0, instock=false 
// id[118748], stocklevel=2445, instock=true

编辑更新以符合我们在评论中讨论的要求。

您可以执行以下操作,这比我认为的实现要简单一些。我还使用了
forEach
reduce
,它们是ES5,但应该适用于现代浏览器。如果您正在使用对于较早的、不兼容ES5的浏览器:

var data = [
  { "id": 118748, "price":"", "stocklevel": 0,   "instock": false, "pname": "Apple TV" },
  { "id": 118805291, "price":"", "stocklevel": 432,   "instock": true, "pname": "Hitachi TV"},
  { "id": 118801891, "price":"", "stocklevel": 0,   "instock": false, "pname": "Sony TV" },
  { "id": 118748, "price":"", "stocklevel": 2345,   "instock": true, "pname": "Apple TV"}
];

function dedup_and_sum(arr, prop) {
    var seen = {},
        order = [];
    arr.forEach(function(o) {
        var id = o[prop];
        if (id in seen) {
            // keep running sum of stocklevel
            var stocklevel = seen[id].stocklevel + o.stocklevel
            // keep this newest record's values
            seen[id] = o;  
            // upid[118805291], stocklevel=432, instock=truedate stocklevel to our running total
            seen[id].stocklevel = stocklevel;
            // keep track of ordering, having seen again, push to end
            order.push(order.splice(order.indexOf(id), 1));
        }
        else {
            seen[id] = o;
            order.push(id);
        }
    });

    return order.map(function(k) { return seen[k]; });
}

// Get unique records, keeping last record of dups
// and summing stocklevel as we go
var unique = dedup_and_sum(data, 'id');
unique.forEach(function(o) {
    console.log("id[%d], stocklevel=%d, instock=%s", o.id, o.stocklevel, o.instock);
});
// output =>
// id[118805291], stocklevel=432, instock=true
// id[118801891], stocklevel=0, instock=false 
// id[118748], stocklevel=2445, instock=true

编辑更新以符合我们在评论中讨论的要求。

感谢您的回答,但是我认为我没有很好地解释我自己……您知道(请注意更新的jsonData)我希望在Json数据中求和库存水平的总和,因此在上面的示例中,我们删除id为118748的第一项,并将库存水平添加到第二项(或相同id的最终出现项),因此,在上述情况下,id:118748的第一次出现被删除,其库存水平被汇总到第二次出现,即2445 OK,因此当您删除DUP时,您希望库存水平是该特定
id
的所有库存水平的运行总和,对吗?我已经更新了问题-我真的很抱歉融合你和解释的东西太糟糕了,应该可以了。我将求和功能移到了
dedup
函数中,将其重命名为
dedup_和_sum
,这样它就可以使用该id在最近看到的记录上保持一个总的库存水平。这很好,但是定位错误,我想要id[118748]作为out OUTPUTED数组中的最后一项,而不是第一项,数组中的顺序应该是一行,以取代该id的最新出现。但是您所做的是一个很大的帮助,并真正教育了我!感谢您的伟大回答,但我认为我没有很好地解释我自己…您看到了(请注意更新的jsonData)我希望在Json数据中求和库存水平的总和,因此在上面的示例中,我们删除id为118748的第一项,并将库存水平添加到第二项(或相同id的最终出现项),因此,在上述情况下,id:118748的第一次出现被删除,其库存水平被汇总到第二次出现,即2445 OK,因此当您删除DUP时,您希望库存水平是该特定
id
的所有库存水平的运行总和,对吗?我已经更新了问题-我真的很抱歉融合你和解释的东西太糟糕了,应该可以了。我将求和功能移到了
dedup
函数中,将其重命名为
dedup_和_sum
,这样它就可以使用该id在最近看到的记录上保持一个总的库存水平。这很好,但是定位错误,我想要id[118748]要成为out OUTPUTED数组中的最后一项,而不是第一项,数组中的顺序应该是一行来代替该id的最新出现。但是您所做的是一个很大的帮助,并真正教育了我!