Javascript 在数组中查找重复的对象,并将具有重复数的对象的新数组作为新属性返回

Javascript 在数组中查找重复的对象,并将具有重复数的对象的新数组作为新属性返回,javascript,arrays,object,filter,Javascript,Arrays,Object,Filter,因此,我有一个对象数组,例如: let arrayOfObjects = [ { Name: "Apple", Type: "Fruit" }, { Name: "Carrot", Type: "Vegetable" }, { Name: "Carrot", Type: "Vegetable" }, { Name: "Carrot", Type: "Vegetable" }, { Name

因此,我有一个对象数组,例如:

let arrayOfObjects = [
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  }
];
counterObj = {
    AppleFruit: {
        Name:"Apple",
        Type:"Fruit",
        times:3,
    },
    CarrotVegetable:{
        Name:"Carrot",
        Type:"Vegetable",
        times:4,
    }
}
我需要遍历它,找到重复项,然后为每个重复项只返回一个对象,但将重复项的数量作为一个新参数

所以像这样:

let newArrayOfObjects = [
  {
    Name: "Apple",
    Type: "Fruit",
    times: 3,
  },
  {
    Name: "Carrot",
    Type: "Vegetable",
    times: 4,
  }
];

我可以根据一个参数计算重复的对象,但我不知道如何根据整个对象进行计算。解决这个问题的最好办法是什么

我认为创建辅助对象最适合您。助手对象最初是空的,但会慢慢地由您正在阅读的内容填充。我假设数组中的键是一致的

const keys = ["Name","Type"]
var counterObj = {}
let keyForCounterObj
arrayOfObjects.forEach((obj)=>{
    keyForCounterObj = ''
    keys.forEach((key)=>{
        keyForCounterObj += String(obj[key])
}
if(counterObj[keyForCounterObj]){
    counterObj[keyForCounterObj].times ++
}else{
    counterObj[keyForCounterObj] = {
        ...obj,
        times:1
}}}
让我们来分析一下,因为我知道如果您以前从未见过这种设置,可能会有点困惑

我们循环遍历数组中的每个对象,并基于该对象存储的所有值构造一个键。例如,arrayOfObjects[0]将创建一个AppleFruit键。我使用String方法只是为了防止它被应用到只有整型值或浮点值的对象,因为这些值对于在javaScript中创建键是无效的。这对于你的具体问题是没有必要的

一旦我们有了那个键,我们就检查它是否存在于我们的反对象中。如果它不存在,那么我们定义它。我们将times属性设置为1,因为我们刚刚创建了这个对象;除非我们刚刚找到它,否则它不会存在

如果对象确实存在,那么我们只需增加times属性。最后,我们有一个如下所示的对象:

let arrayOfObjects = [
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  }
];
counterObj = {
    AppleFruit: {
        Name:"Apple",
        Type:"Fruit",
        times:3,
    },
    CarrotVegetable:{
        Name:"Carrot",
        Type:"Vegetable",
        times:4,
    }
}
好的,现在我们有一个物体的物体。让我们把它变成一个数组

let newArrayOfObjects = []
const counterObjKeys = Object.keys(counterObj)
counterObjKeys.forEach((key)=>{
    newArrayOfObjects.push(counterObj[key])
}

这将以您指定的格式返回最终值

我认为创建辅助对象最适合您。助手对象最初是空的,但会慢慢地由您正在阅读的内容填充。我假设数组中的键是一致的

const keys = ["Name","Type"]
var counterObj = {}
let keyForCounterObj
arrayOfObjects.forEach((obj)=>{
    keyForCounterObj = ''
    keys.forEach((key)=>{
        keyForCounterObj += String(obj[key])
}
if(counterObj[keyForCounterObj]){
    counterObj[keyForCounterObj].times ++
}else{
    counterObj[keyForCounterObj] = {
        ...obj,
        times:1
}}}
让我们来分析一下,因为我知道如果您以前从未见过这种设置,可能会有点困惑

我们循环遍历数组中的每个对象,并基于该对象存储的所有值构造一个键。例如,arrayOfObjects[0]将创建一个AppleFruit键。我使用String方法只是为了防止它被应用到只有整型值或浮点值的对象,因为这些值对于在javaScript中创建键是无效的。这对于你的具体问题是没有必要的

一旦我们有了那个键,我们就检查它是否存在于我们的反对象中。如果它不存在,那么我们定义它。我们将times属性设置为1,因为我们刚刚创建了这个对象;除非我们刚刚找到它,否则它不会存在

如果对象确实存在,那么我们只需增加times属性。最后,我们有一个如下所示的对象:

let arrayOfObjects = [
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  },
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Apple",
    Type: "Fruit"
  },
  {
    Name: "Carrot",
    Type: "Vegetable"
  }
];
counterObj = {
    AppleFruit: {
        Name:"Apple",
        Type:"Fruit",
        times:3,
    },
    CarrotVegetable:{
        Name:"Carrot",
        Type:"Vegetable",
        times:4,
    }
}
好的,现在我们有一个物体的物体。让我们把它变成一个数组

let newArrayOfObjects = []
const counterObjKeys = Object.keys(counterObj)
counterObjKeys.forEach((key)=>{
    newArrayOfObjects.push(counterObj[key])
}

这将以您指定的格式返回最终值

您可以在对象数组中循环,同时使用对象来保存某个名称出现的次数。然后循环遍历新的对象数组,并从持有计数器的对象中指定时间键

let arrayOfObjects = [
  {Name: "Apple", Type: "Fruit"},
  {Name: "Carrot", Type: "Vegetable"},
  {Name: "Carrot", Type: "Vegetable"},
  {Name: "Carrot", Type: "Vegetable"},
  {Name: "Apple", Type: "Fruit"},
  {Name: "Apple", Type: "Fruit"},
  {Name: "Carrot", Type: "Vegetable"}
];
let newArrayOfObjects = [];
// object that holds how many times a "Name" value appears.
var uniqueNames = {};
// loop through array of objects
for (var i = 0; i < arrayOfObjects.length; i++) {
  // if uniqueNames key does not exist
  if (!uniqueNames[arrayOfObjects[i].Name]) {
    // push this object into new array
    newArrayOfObjects.push(arrayOfObjects[i]);
  }
  // use this as a counter for each "Name" value
  uniqueNames[arrayOfObjects[i].Name] = ((uniqueNames[arrayOfObjects[i].Name] || 0) + 1);
}
// loop through new array of objects, and add the "times" key to it
for (var j = 0; j < newArrayOfObjects.length; j++) {
  newArrayOfObjects[j].times = uniqueNames[newArrayOfObjects[j].Name];
}
console.log(newArrayOfObjects);

您可以在对象数组中循环,同时使用对象来保存某个名称出现的次数。然后循环遍历新的对象数组,并从持有计数器的对象中指定时间键

let arrayOfObjects = [
  {Name: "Apple", Type: "Fruit"},
  {Name: "Carrot", Type: "Vegetable"},
  {Name: "Carrot", Type: "Vegetable"},
  {Name: "Carrot", Type: "Vegetable"},
  {Name: "Apple", Type: "Fruit"},
  {Name: "Apple", Type: "Fruit"},
  {Name: "Carrot", Type: "Vegetable"}
];
let newArrayOfObjects = [];
// object that holds how many times a "Name" value appears.
var uniqueNames = {};
// loop through array of objects
for (var i = 0; i < arrayOfObjects.length; i++) {
  // if uniqueNames key does not exist
  if (!uniqueNames[arrayOfObjects[i].Name]) {
    // push this object into new array
    newArrayOfObjects.push(arrayOfObjects[i]);
  }
  // use this as a counter for each "Name" value
  uniqueNames[arrayOfObjects[i].Name] = ((uniqueNames[arrayOfObjects[i].Name] || 0) + 1);
}
// loop through new array of objects, and add the "times" key to it
for (var j = 0; j < newArrayOfObjects.length; j++) {
  newArrayOfObjects[j].times = uniqueNames[newArrayOfObjects[j].Name];
}
console.log(newArrayOfObjects);

您可以将.map与原始数组相结合,并使用.find搜索新形成数组的项

设arrayOfObjects=[ { 名称:苹果, 种类:水果 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名称:苹果, 种类:水果 }, { 名称:苹果, 种类:水果 }, { 名字:胡萝卜, 种类:蔬菜 } ]; 常量结果数组=[]; arrayOfObjects.mapitem=>{ //对于arrayOfObjects中的每个项,检查结果数组中是否存在该对象 ifresultArray.findobject=>{ ifobject.Name==item.Name&&object.Type==item.Type{ //如果对象存在,则迭代次数 object.times++; 返回true; //如果不返回false }否则{ 返回false; } }{ }否则{ //如果对象不存在,则将其推送到结果数组,并将时间计数设置为1 item.times=1; resultArray.pushitem; } }
console.logresultArray您可以结合使用原始数组上的.map和使用.find搜索新形成的数组中的项

设arrayOfObjects=[ { 名称:苹果, 种类:水果 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名称:苹果, 种类:水果 }, { 名称:苹果, 种类:水果 }, { 名字:胡萝卜, 种类:蔬菜 } ]; 常量结果数组=[]; arrayOfObjects.mapitem=>{ //对于arrayOfObjects中的每个项,检查结果数组中是否存在该对象 ifresultArray.findobject=>{ ifobject.Name==item.Name&&object.Type==item.Type{ //如果对象存在,则迭代次数 object.times++; 返回true; //如果不返回false }否则{ 返回false; } }{ }否则{ //如果对象不存在,则将其推送到结果数组,并将时间计数设置为1 item.times=1; resultArray.pushitem; } } console.logresultArray可以使用reduce方法完成:

常量数组对象=[ { 名称:苹果,类型:水果 }, { 名称:胡萝卜,类型:蔬菜 }, { 名称:胡萝卜,类型:蔬菜 }, { 名称:胡萝卜,类型:蔬菜 }, { 名称:苹果,类型:水果 }, { 名称:苹果,类型:水果 }, { 名称:胡萝卜,类型:蔬菜 } ]; const result=arrayOfObjects.reducea,{Name,Type}=>{ a[Name]=a[Name]|{Name,Type,times:0}; a[名称]。次数+=1; 返回a; }, {} console.logObject.valuesresult 可以使用以下方法进行减少:

常量数组对象=[ { 名称:苹果,类型:水果 }, { 名称:胡萝卜,类型:蔬菜 }, { 名称:胡萝卜,类型:蔬菜 }, { 名称:胡萝卜,类型:蔬菜 }, { 名称:苹果,类型:水果 }, { 名称:苹果,类型:水果 }, { 名称:胡萝卜,类型:蔬菜 } ]; const result=arrayOfObjects.reducea,{Name,Type}=>{ a[Name]=a[Name]|{Name,Type,times:0}; a[名称]。次数+=1; 返回a; }, {}
console.logObject.valuesresult 只需使用嵌套过滤器操作执行映射操作,即可获得重复对象的出现次数。简单

设arrayOfObjects=[{ 名称:苹果, 种类:水果 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名称:苹果, 种类:水果 }, { 名称:苹果, 种类:水果 }, { 名字:胡萝卜, 种类:蔬菜 }]; var returnedArray=[]; 函数countNumberInobj,数组{ return array.filterfunctionobject{ 返回object.Name==obj.Name&&object.Type==obj.Type }.长度; } arrayOfObjects.mapfunctionobj{ obj.count=countNumberInobj,arrayofoobjects; 返回obj; }.forEachfunctionobj{ 如果countNumberInobj,则返回数组==0{ 返回Array.pushobj; } };
console.logreturnedArray 只需使用嵌套过滤器操作执行映射操作,即可获得重复对象的出现次数。简单

设arrayOfObjects=[{ 名称:苹果, 种类:水果 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名字:胡萝卜, 种类:蔬菜 }, { 名称:苹果, 种类:水果 }, { 名称:苹果, 种类:水果 }, { 名字:胡萝卜, 种类:蔬菜 }]; var returnedArray=[]; 函数countNumberInobj,数组{ return array.filterfunctionobject{ 返回object.Name==obj.Name&&object.Type==obj.Type }.长度; } arrayOfObjects.mapfunctionobj{ obj.count=countNumberInobj,arrayofoobjects; 返回obj; }.forEachfunctionobj{ 如果countNumberInobj,则返回数组==0{ 返回Array.pushobj; } };
console.logreturnedArray;我知道这个可能的解决方案,但它是不需要的,因为它将返回{Name:'Carrot',Type:'vegeture',times:4},即使其中一个对象是这样的:{Name:Carrot,Type:Fruit}。我需要完全匹配对象,而不仅仅是匹配它们的名称。我知道这个可能的解决方案,但它是不需要的,因为它将返回{name:'Carrot',Type:'vegeture',times:4},即使其中一个对象是这样的:{name:Carrot,Type:Fruit}。我需要完全匹配对象,而不仅仅是匹配它们的名称。这似乎是正确的和有效的解决方案。谢谢。很高兴能帮上忙。请让我知道,如果有什么不清楚或挥手。如果需要,我很乐意详细说明。这似乎是正确和有效的解决方案。谢谢。很高兴能帮上忙。请让我知道,如果有什么不清楚或挥手。如果需要的话,我很乐意详细说明。同样,这不是一个受欢迎的解决方案,因为它只根据名称来比较对象。@Esszed是否要按名称和类型进行比较?对不起,你能澄清一下要求是什么吗?问题中提到了。我需要找到重复的对象,而不仅仅是一个重复的参数。重复对象意味着所有参数都相同。同样,这不是一个受欢迎的解决方案,因为它只根据名称比较对象。@Esszed
是否要按名称和类型进行比较?对不起,你能澄清一下要求是什么吗?问题中提到了。我需要找到重复的对象,而不仅仅是一个重复的参数。重复对象意味着所有参数都相同。