AngularJS:如何检查对象数组中是否存在值?

时间:2016-10-26 19:22:20

标签: angularjs arrays object indexof

我试图编写一个迭代对象数组的函数,然后推送新的(具有唯一名称的函数),同时更新已经看过的对象。

比方说,我有这个数组:

$scope.myArray = [
    { "name": "Apple", "total": 16, "applicable": 21 },
    { "name": "Cherry", "total": 12, "applicable": 27 },
    { "name": "Plum", "total": 14, "applicable": 21 },
    { "name": "Apple", "total": 16, "applicable": 21 },
    { "name": "Cherry", "total": 12, "applicable": 27 },
    { "name": "Plum", "total": 14, "applicable": 21 },
    { "name": "Banana", "total": 14, "applicable": 21 },
];

在函数结束时,新数组应为:

$scope.myNewArray = [
    { "name": "Apple", "total": 32, "applicable": 42},
    { "name": "Cherry", "total": 24, "applicable": 54},
    { "name": "Plum", "total": 28, "applicable": 42},
    { "name": "Banana", "total": 14, "applicable": 21 },
];

这是我到目前为止所拥有的:

$scope.myArray = [
    { "name": "Apple", "total": 16, "applicable": 21 },
    { "name": "Cherry", "total": 12, "applicable": 27 },
    { "name": "Plum", "total": 14, "applicable": 21 },
    { "name": "Apple", "total": 16, "applicable": 21 },
    { "name": "Cherry", "total": 12, "applicable": 27 },
    { "name": "Plum", "total": 14, "applicable": 21 },
    { "name": "Banana", "total": 14, "applicable": 21 },
];

$scope.myNewArray = [];

$scope.myArray.filter( function () {

    var i = $scope.myNewArray.indexOf($scope.myArray.name);

    if ($scope.myNewArray.indexOf($scope.myArray.name) < 0)
        $scope.myNewArray.push($scope.myArray);

    else {
        $scope.myNewArray[i].total += $scope.myArray.total;
        $scope.myNewArray[i].applicable += $scope.myArray.applicable;
    }
});

我遇到的问题是所有内容都被推入新阵列。我相信我的其他陈述,我将这些值添加到上一条记录可能是错误的。

此外,为每个名称对数组进行硬编码并不起作用,因为这只是一个带有小数据集的简单示例。

任何人都可以伸出援手吗?

3 个答案:

答案 0 :(得分:2)

尝试这种方法:

  1. 创建对象,其中键是名称属性,总计以及适用的已经计算(Array.prototype.reduce
  2. 迭代先前创建的对象的键并将其转换回数组(Object.keysArray.prototype.map
  3. &#13;
    &#13;
    var res = {};
    res = Object.keys([
        { "name": "Apple", "total": 16, "applicable": 21 },
        { "name": "Cherry", "total": 12, "applicable": 27 },
        { "name": "Plum", "total": 14, "applicable": 21 },
        { "name": "Apple", "total": 16, "applicable": 21 },
        { "name": "Cherry", "total": 12, "applicable": 27 },
        { "name": "Plum", "total": 14, "applicable": 21 },
        { "name": "Banana", "total": 14, "applicable": 21 },
    ].reduce(function (res, item) {
      if (res[item.name]) {
        res[item.name].total += item.total;
        res[item.name].applicable += item.applicable;
      }
      else {
        res[item.name] = item;
      }
      return res; 
    }, res)).map(function(key) {
      return res[key];
    });
    console.log(res);
    &#13;
    &#13;
    &#13;

    添加较少的硬编码解决方案:

    &#13;
    &#13;
    var myArray = [
      { "name": "Apple", "total": 16, "applicable": 21 },
      { "name": "Cherry", "total": 12, "applicable": 27 },
      { "name": "Plum", "total": 14, "applicable": 21 },
      { "name": "Apple", "total": 16, "applicable": 21 },
      { "name": "Cherry", "total": 12, "applicable": 27 },
      { "name": "Plum", "total": 14, "applicable": 21 },
      { "name": "Banana", "total": 14, "applicable": 21 },
    ];
    
    var res = {};
      
    // add keys for loopable integers which will be summed   
    var loopables = Object.keys(myArray[0]).filter(function (key) {
      return Number.isInteger(myArray[0][key]);
    });
    
    res = Object.keys(myArray.reduce(function (res, item) {
      if (res[item.name]) {
        loopables.forEach(function (loopableKey) {
          res[item.name][loopableKey] += item[loopableKey];
        });
        
      }
      else {
        res[item.name] = item;
      }
      return res; 
    }, res)).map(function(key) {
      return res[key];
    });
    console.log(res);
    &#13;
    &#13;
    &#13;

    这里我只依赖主键 name ,其余的整数属性会自动求和,通过迭代 loopables 键数组,在开头计算

    使用Angular的攻击者:https://plnkr.co/edit/MRr2QRULG8TYs2CqA1By?p=preview

答案 1 :(得分:1)

我对这些事情的处理方式是我使用angular forEach,在你的情况下,我会制作三个不同的数组并用这些信息填充它们。然后我在它们上使用indexof并将它们推送到myNewArray。它比简单对象更容易处理简单数组。

例如onEach Angular forEach

答案 2 :(得分:1)

我认为你可以在纯粹的javascript中完成它

检查以下代码段

  var obj = [{
            "name": "Apple",
            "total": 16,
            "applicable": 21
}, {
            "name": "Cherry",
            "total": 12,
            "applicable": 27
}, {
            "name": "Plum",
            "total": 14,
            "applicable": 21
}, {
            "name": "Apple",
            "total": 16,
            "applicable": 21
}, {
            "name": "Cherry",
            "total": 12,
            "applicable": 27
}, {
            "name": "Plum",
            "total": 14,
            "applicable": 21
}, {
            "name": "Banana",
            "total": 14,
            "applicable": 21
}, ];

        var newObj = [];

        MergeObjectProperties(obj);

        function MergeObjectProperties(obj) {
            Object.keys(obj).forEach(function (key) {
                var name = obj[key].name;
                var exists = checkProperty(name, newObj)
                if (newObj.length == 0 || !exists)
                    newObj.push(obj[key]);
                else {
                    newObj[exists]["total"] = obj[key].total + newObj[exists]["total"];
                    newObj[exists]["applicable"] = obj[key].applicable + newObj[exists]["applicable"];
                }
            });
         console.log(newObj);
        }

        function checkProperty(prop, newObj) {
            var result;
            Object.keys(newObj).forEach(function (key) {
                if (newObj[key]["name"] === prop) {
                    result = key
                }
            });
            return result;
        }

希望这有帮助