【问题标题】:AngularJS: How to check if value exists in array of objects?AngularJS:如何检查对象数组中是否存在值?
【发布时间】:2017-03-09 07:25:20
【问题描述】:

我正在尝试编写一个函数,它遍历对象数组,并推入新对象(具有唯一名称的对象),同时更新已经看到的对象。

比如说,我有这个数组:

$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;
    }
});

我遇到的问题是所有内容都被推入新数组。那我相信我将值添加到上一条记录的 else 语句可能是错误的。

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

有人可以帮忙吗?

【问题讨论】:

  • 我要做的就是简单地使用 angular forEach ,在你的情况下,我会制作三个不同的数组并用这些信息填充它们。然后我会对它们使用 indexof 并将它们推送到 myNewArray。处理简单数组比处理数组对象更容易。
  • @ThatBird 希望我能做到这一点,不幸的是,这只是我想要完成的一个简单版本。所以在这个例子中,三个数组可以工作,但对于更大的数据集,它就不行了。另外,使用您建议的方法,这不会是动态的。而是硬编码
  • 嗯,我已经用这种方法处理了大约 50,000 个值(大部分超过这个值),我从来没有遇到任何麻烦。虽然是的,但您必须事先知道您将在数据对象中收到什么(在您的情况下为 myArray)
  • @thatbird,你是对的 :) 可能不得不采用这个解决方案
  • 我也会将此作为答案发布,如果您遇到问题,请告诉我!

标签: angularjs arrays object indexof


【解决方案1】:

试试这个方法:

  1. 创建对象,其中键是 name 属性和 total 以及 applicable 已经计算 (Array.prototype.reduce)
  2. 遍历先前创建的对象的键并将其转换回数组(Object.keysArray.prototype.map

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);

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

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);

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

使用 Angular 的插件:https://plnkr.co/edit/MRr2QRULG8TYs2CqA1By?p=preview

【讨论】:

  • 这很糟糕,但是如果没有明确说明对象数组,你能解释一下上面的代码是如何工作的吗?意思是,不是将数组硬编码出来,而是已经设置为变量?例如,$scope.myArray。我问是因为你有 reduce 函数中间数组声明。
  • 用另一个 sn-p 更新了我的答案,其中数组在变量中,并且以编程方式计算总和值
【解决方案2】:

我认为你可以用纯 javascript 做到这一点

检查以下 sn-p

  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;
        }

希望对你有帮助

【讨论】:

    【解决方案3】:

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

    例如在 forEach Angular forEach.

    【讨论】:

      猜你喜欢
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-21
      • 1970-01-01
      • 2012-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多