创建对象数组并计算出现次数

时间:2017-04-30 07:14:34

标签: javascript

我有一个对象数组,想要创建另一个对象数组。 我想检查一个对象是否重复只是想显示计数,否则用count = 1显示对象本身。

<!-- I have an array--> 
 var arr =[{name:"coke",price:20},{name:"coke",price:20},{name:"coke",price:20},{name:"kabab",price:250}];
 // I want to create another array based on "arr" like the one below
var test =[{name:"coke",price:20,count:3},{name:"kabab",price:20,count:1}];

//Any hint please

7 个答案:

答案 0 :(得分:0)

这可能会对你有所帮助。这个答案考虑name或某些标识符对每个对象都是唯一的。

counter = {}
var arr = [{
  name: "coke",
  price: 20
}, {
  name: "coke",
  price: 20
}, {
  name: "coke",
  price: 20
}, {
  name: "kabab",
  price: 250
}];

var obj = {};
var counter = {}

for (var i = 0, len = arr.length; i < len; i++) {
  obj[arr[i]['name']] = arr[i];
  counter[arr[i]['name']] = (counter[arr[i]['name']] || 0) + 1
}
newArr = new Array();
for (var key in obj){
  newArr.push(extend( obj[key], {count:counter[key]}));
}

function extend(a, b){
    for(var key in b)
        if(b.hasOwnProperty(key))
            a[key] = b[key];
    return a;
}
console.log(newArr)

答案 1 :(得分:0)

 var arr =[{name:"coke",price:20},{name:"coke",price:20},{name:"coke",price:20},{name:"kabab",price:250}];
 var countNameMapping = {}, finalArr = [];

 var arrLength = arr.length;
 for(i=0; i<arrLength; i++){
    var tempObj = {name:arr[i], price:arr[i].price, occurance:1};
    var productName = arr[i].name;
    if(countNameMapping[productName] === undefined){
        countNameMapping[productName] = tempObj; 
    }else{
        countNameMapping[productName].occurance += 1;
    }
 }

 for(var k in countNameMapping){
    finalArr.push(countNameMapping[k])
 }
 console.log(finalArr );

答案 2 :(得分:0)

你可以尝试这个:

var arr =[{name:"coke",price:20},{name:"coke",price:20},{name:"coke",price:20},{name:"kabab",price:250}];

var result = [];

arr.map(function(arrObject) {
    if (result.length > 0) {
        result.map(function(resultObject) {
            if (resultObject.name != arrObject.name) {
                arrObject.count = 1;
                result.push(arrObject);
            } else {
                resultObject.count++;
            }
        })
    } else {
        arrObject.count = 1;
        result.push(arrObject);
    }
})

console.log(result);

答案 3 :(得分:0)

这将提供您正在寻找的结果:

var arr =[{name:"coke",price:20},{name:"coke",price:20},{name:"coke",price:20},{name:"kabab",price:250}];

var map = arr.reduce((accum, item) => {
  var obj = accum.get(item.name) || Object.assign({}, item, {count:0});
  obj.count++;
  return accum.set(item.name, obj);
}, new Map());
var res = [...map.values()];

答案 4 :(得分:-1)

或多或少......

&#13;
&#13;
var arr = [{
  name: "coke",
  price: 20
}, {
  name: "coke",
  price: 20
}, {
  name: "coke",
  price: 20
}, {
  name: "kabab",
  price: 250
}];
// I want to create another array based on "arr" like the one below
// var test =[{name:"coke",price:20,count:3},{name:"kabab",price:20,count:1}];
var count = {};
var test = [];
for (var i = 0, len = arr.length; i < len; i++) {
  var id = JSON.stringify(arr[i]);
  if (count.hasOwnProperty(id)) {
    count[id].count++;
  } else {
    test.push(arr[i]); // Data contamination. Too lazy to copy object
    count[id] = test[test.length - 1]; // Could be better.
    count[id].count = 1;
  }
}
console.log(test);
&#13;
&#13;
&#13;

答案 5 :(得分:-1)

这是一个非常快速,肮脏和苛刻的解决方案,但仍然是一个解决方案。

function countObjects(objects) {
  return Object.values(objects.reduce((result, item) => {
    const index = `${item.name}-${item.price}`;
    const count = result[index] ? result[index].count : 0;

    return {
      ...result,
      [index]: {
        ...item,
        count: count + 1,
      },
    };
  }, {}));
}

它是如何工作的?您将数组传递给函数,并调用Array对象的reduce方法。减少通过数组的“循环”并调用一个函数,您将其作为第一个参数传递给它。匿名函数检索应该由reduce返回的变量。初始变量作为第二个参数传递给reduce({})。

所以我们正在构建一个新对象。对于数组的每个对象,我们使用名称和价格在新对象中构建键。因此,如果具有相同属性的对象到达,我们将覆盖现有密钥。我们计算每个对象的计数器。

最后,我们调用Object.values来检索对象中的每个值并将其传递给一个新的数组,我们的函数可以返回它。

答案 6 :(得分:-1)

这可能就是你要找的东西:

它是如何工作的? 首先,您的数组arr将使用forEach循环查找每个object,如果是新的,则将其添加到results数组。如果对象是新的,方法isNew()将返回true

对于每个创建的新对象,您将使用findOccurrences()计算出现次数。减少&#34;循环次数&#34;你将根据索引切片数组。因此,您无需再次搜索已处理的数据。

现在,您可以使用名称,价格和计数构建新对象

最后,您可以push() 新对象results数组。

&#13;
&#13;
var arr =[{name:"coke",price:20},{price:20,name:"coke"},{name:"coke",price:20},{name:"kabab",price:250}];
var results = [];
var index = 0;

var originalDiv = document.getElementById('original');
var resultsDiv = document.getElementById('results');

arr.forEach(function(obj) {
  if (isNew(obj)) {
    var counter = findOccurrences(obj, arr.slice(index, arr.length));
    var newObj = {
      name: obj.name,
      price: obj.price,
      count: counter
    }
    results.push(newObj);
  }
  index++;
});


printArray(arr, originalDiv);
printArray(results, resultsDiv);



function isNew(newObj) {
  var wasFound = true;
  if (typeof results != "undefined" && results != null && results.length > 0) {
    results.forEach(function(obj) {
      if (newObj.name === obj.name && newObj.price === obj.price) {
        return false;
      } else {
        wasFound = false;
      }
    });
    return !wasFound;
  } else {
    return true;
  }
}

function findOccurrences(newObj, objects) {
  var count = 0;
  if (typeof objects != "undefined" && objects != null && objects.length > 0) {
    objects.forEach(function(obj) {
      if (newObj.name === obj.name && newObj.price === obj.price) {
        count++;
      }
    });
  }
  return count;
}

function printArray(objects, div) {
  var count = 0;
  if (typeof objects != "undefined" && objects != null && objects.length > 0) {
    objects.forEach(function(obj) {
      var newElement = document.createElement('p');
      newElement.innerHTML = 'item ' + count + ': ';
      Object.keys(obj).forEach(function(key) {
        newElement.innerHTML += key + ': ' + obj[key] + ', ';
      });
      newElement.innerHTML = newElement.innerHTML.slice(0, -2);
      div.appendChild(newElement);
      count++;
    });
  }
}
&#13;
<div id="original"><p>Original Array</p></div>
<div id="results"><p>Results Array</p></div>
&#13;
&#13;
&#13;

<强>更新: 更多优化。

&#13;
&#13;
var arr =[{name:"coke",price:20},{name:"coke",price:20},{name:"coke",price:20},{name:"kabab",price:250},{name:"coke",price:20},{name:"coke",price:20},{name:"kabab",price:250}];
var accumulator = {};
var results = [];

var index = 0;

var originalDiv = document.getElementById('original');
var resultsDiv = document.getElementById('results');

String.prototype.hashCode = function() {
  var hash = 0;
  if (this.length == 0) return hash;
  for (i = 0; i < this.length; i++) {
    var char = this.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash |= 0; // Convert to 32bit integer
  }
  
  var c = (hash & 0x0FFFFFFF)
    .toString(16)
    .toUpperCase();

  return '0000000'.substring(0, 7 - c.length) + c;
};

arr.forEach(function(obj) {
  var id = JSON.stringify(obj).hashCode();
  console.log(id);
  if (accumulator.hasOwnProperty(id)) {
    accumulator[id].count++;
  } else {
    results.push(obj);
    accumulator[id] = results[results.length - 1];
    accumulator[id].count = 1;
  }
});

printArray(arr, originalDiv);
printArray(results, resultsDiv);

function printArray(objects, div) {
  var count = 0;
  if (typeof objects != "undefined" && objects != null && objects.length > 0) {
    objects.forEach(function(obj) {
      var newElement = document.createElement('p');
      newElement.innerHTML = 'item ' + count + ': ';
      Object.keys(obj).forEach(function(key) {
        newElement.innerHTML += key + ': ' + obj[key] + ', ';
      });
      newElement.innerHTML = newElement.innerHTML.slice(0, -2);
      div.appendChild(newElement);
      count++;
    });
  }
}
&#13;
<div id="original">
  <p>Original Array</p>
</div>
<div id="results">
  <p>Results Array</p>
</div>
&#13;
&#13;
&#13;