如果我有一个包含对象的数组,我该如何找出该数组中最常出现的对象?
让我们说数组是一个包含产品的数组,每个产品都是一个具有唯一ID的对象(每个产品唯一的不是数组中的每个元素):
const products = [
{
"itemId": "573412ab18c933d0085ca8b2",
"price": 20,
"cartQuantity": 1,
"itemName": "Tea"
},
{
"itemId": "573c82bd5c5ade1100532ec0",
"price": 100,
"cartQuantity": 1,
"itemName": "Carpet"
},
{
"itemId": "5734126218c933d0085ca8b0",
"_id": "57608d4187faf12708605360",
"price": 15,
"cartQuantity": 1,
"itemName": "Black Coffee"
},
{
"itemId": "573412dd18c933d0085ca8b3",
"_id": "57608d3d87faf12708605362",
"price": 50,
"cartQuantity": 1,
"itemName": "Nyquil"
},
{
"itemId": "573412ab18c933d0085ca8b2",
"price": 20,
"cartQuantity": 1,
"itemName": "Tea"
}
];
在上面的代码片段中,您可以看到" Tea"最常发生。我目前缺乏必要的算法知识,无法弄清楚如何吸取"茶"该数组中的对象是最常出现的元素。此外,如果有人可以在这里帮助我,重要的是要记住一个异常情况,即阵列中的两个元素出现的次数相同,并且它们会相互关联。因为最常见。
如果这对于某人来说是一个容易解决的问题,请轻松解释我并详细解释,因为您的耐心允许您如何解决这个问题,因为我还在学习。随意用下划线或lodash函数回答!
答案 0 :(得分:0)
我认为最简单的方法是遍历数组并将当前产品的每个itemId作为一个键添加到对象中(包含计数为1的值,以及数组中的索引)。
如果元素已经在对象中,则将计数值递增1.最后,您只需找到对象中的最大计数值。
解决方案:
function mostOccuringProduct(productList) {
const frequencies = {};
// iterating through each product counting the occurrence of each itemId
productList.forEach((product, i) => {
if (product.itemId in frequencies) {
frequencies[product.itemId].count++;
} else {
frequencies[product.itemId] = { count: 1, index: i };
}
})
// find max number of occurences of any 1 item
const maxOccurences = _.max(frequencies, item => item.count);
// get array of items that tie for this maxOccurences #
const itemsMatchingMaxOccurences = _.filter(frequencies, item => item.count === maxOccurences.count);
// create array of just the indicies of the items that tie for the maxNumber of occurences
const indicesOfMaxOccuringItems = _.map(itemsMatchingMaxOccurences, frequency => frequency.index);
// initialize an array to hold all items that tie for max occurencies
const products = [];
// push items to this array
indicesOfMaxOccuringItems.forEach(index => products.push(productList[index]));
// return an array of all products that occur most frequently.
// or just return the product that occurs most IF there is only one.
return products.length > 1 ? products : products[0];
}
此解决方案将返回一系列产品,这些产品与列表中出现次数最多的产品相关联。如果只有一个项目,它将返回1个项目。
答案 1 :(得分:0)
您可以将输出格式化为:
[
{
"itemId": "573412ab18c933d0085ca8b2",
"ocurrences": 2
},
{
"itemId": "573c82bd5c5ade1100532ec0",
"ocurrences": 1
},
...
]
什么是排序数组,其中第一个元素是数组中重复次数最多的元素。按照排序,您可以轻松检查第二个或下一个元素是否具有相同的发生次数。
要实现这一目标,你需要这样的东西:
let getOcurrences = array =>{
let ocurrences = {};
array.forEach(item=>{
if (!ocurrences[item.itemId])
ocurrences[item.itemId] = 1;
else
ocurrences[item.itemId] += 1;
});
return Object.keys(ocurrences)
.map(itemId => ({
itemId : itemId,
ocurrences : ocurrences[itemId]
}))
.sort((a, b)=> b.ocurrences - a.ocurrences);
};
const products = [
{
"itemId": "573412ab18c933d0085ca8b2",
"price": 20,
"cartQuantity": 1,
"itemName": "Tea"
},
{
"itemId": "573c82bd5c5ade1100532ec0",
"price": 100,
"cartQuantity": 1,
"itemName": "Carpet"
},
{
"itemId": "5734126218c933d0085ca8b0",
"_id": "57608d4187faf12708605360",
"price": 15,
"cartQuantity": 1,
"itemName": "Black Coffee"
},
{
"itemId": "573412dd18c933d0085ca8b3",
"_id": "57608d3d87faf12708605362",
"price": 50,
"cartQuantity": 1,
"itemName": "Nyquil"
},
{
"itemId": "573412ab18c933d0085ca8b2",
"price": 20,
"cartQuantity": 1,
"itemName": "Tea"
}
];
console.log(getOcurrences(products));
答案 2 :(得分:0)
我建议使用hashmap来计算出现的次数,同时迭代产品&跟踪最常见的产品:
function getMostFrequent(array, identityFn) {
var counts = {}, max = 0, result;
array.forEach(element => {
var id = (identityFn && identityFn(element)) || element,
count = counts[id] = (counts[id] || 0) + 1;
if (count > max) {
max = count;
result = element;
}
});
return result;
}
const products = [{"itemId": 1}, {"itemId": 2}, {"itemId": 2}, {"itemId": 3}];
var mostFrequent = getMostFrequent(products, p => p["itemId"]);
console.log(mostFrequent);
如果您希望所有产品与最常用的产品相关联,而不仅仅是第一个产品,请将结果声明为Array
并在count == max
上推送元素。
getMostFrequent()
的说明:
我们遍历给定array
中的所有元素以及每个元素...
id
回调函数获取identityFn
id
counts[id] = (counts[id] || 0) + 1;
的计数器
答案 3 :(得分:0)
这是我的 O(n)解决方案。我们创建一个哈希表,并将哈希表中的计数保存在一个名为indices的单独属性中,这是一个数组。当项目首次出现时,它的索引值(在products数组中)将被插入到索引数组索引位置1.当另一个项目首次出现时,它将覆盖索引位置1。因此,当项目第二次出现时,它会在索引[2]处插入,依此类推。最后,indices.pop()将为我们提供最频繁的产品项目索引,而且我们不会改变产品数组。
var products = [
{
"itemId": "573412ab18c933d0085ca8b2",
"price": 20,
"cartQuantity": 1,
"itemName": "Tea"
},
{
"itemId": "573c82bd5c5ade1100532ec0",
"price": 100,
"cartQuantity": 1,
"itemName": "Carpet"
},
{
"itemId": "5734126218c933d0085ca8b0",
"_id": "57608d4187faf12708605360",
"price": 15,
"cartQuantity": 1,
"itemName": "Black Coffee"
},
{
"itemId": "573412dd18c933d0085ca8b3",
"_id": "57608d3d87faf12708605362",
"price": 50,
"cartQuantity": 1,
"itemName": "Nyquil"
},
{
"itemId": "573412ab18c933d0085ca8b2",
"price": 20,
"cartQuantity": 1,
"itemName": "Tea"
}
],
lut = products.reduce((p,c,i) => { ++p[c.itemId] || (p[c.itemId] = 1);
p.indices[p[c.itemId]] = i;
return p;
},{indices:[]});
console.log(lut);
console.log(products[lut.indices[lut.indices.length-1]]);