遍历对象数组并根据属性添加它们 [英] Loop through array of objects and add them based on a property

查看:68
本文介绍了遍历对象数组并根据属性添加它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象如下的数组。

  0:Object 
BARKOD: Pa Detatime
DETAJIM1:
DETAJIM2:
DTMODIFIKIM: 2017-10-02T16:06:53.206Z
KODARTIKULLI: SD13137
KODI: MX02
KODNJESIA1:应付
PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56
cmimibaze:0
gjendje:1
1:对象
BARKOD : Pa Detatime
DETAJIM1:
DETAJIM2:
DTMODIFIKIM: 2017-10-02T16:06:53.206Z
KODARTIKULLI: SD13137
KODI: MX02
KODNJESIA1:应付
PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56
cmimibaze:0
gjendje:1
2:对象
BARKOD: Pa Detatime
DETAJIM1:
DETAJIM2:
DTMODIFIKIM: 2017-10-02T16:06:53.206Z
KODARTIKULLI : SD13137
KODI: MX03
KODNJESIA1:应付
PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56
cmimibaze:0
gjendje:1
3:对象
BARKOD: Pa Detatime
DETAJIM1:
DETAJIM2:
DTMODIFIKIM: 2017-10-02T16:06:53.206Z
KODARTIKULLI: SD13141
KODI: MX02
KODNJESIA1:应付
PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56
cmimibaze:0
gjendje:1

现在,我想使用以下2个属性删除重复项: KODI KODARTIKULLI ,例如在您可以看到前两个对象 KODI KODARTIKULLI 是相同的,所以我只想保留



第二个问题更重要,甚至可以解决第一个问题。这些对象是取自不同存储单元的产品( KODI代表存储单元ID)。因此,我想要一个独特的产品(产品ID为 KODARTIKULLI)来添加所有可用的单位(可用的单位存储在 gjendje中)。这似乎有点复杂,但是我希望上面的数组看起来像下面这样:

  0:Object 
BARKOD : Pa Detatime
DETAJIM1:
DETAJIM2:
DTMODIFIKIM: 2017-10-02T16:06:53.206Z
KODARTIKULLI: SD13137
KODI: MX02
KODNJESIA1:应付
PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56
cmimibaze:0
gjendje:2
1:对象
BARKOD: Pa Detatime
DETAJIM1:
DETAJIM2:
DTMODIFIKIM: 2017-10-02T16:06:53.206Z
KODARTIKULLI : SD13141
KODI: MX02
KODNJESIA1:应付
PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56
cmimibaze:0
gjendje:1

因此,由于前两个对象是同一产品且来自同一存储单元,因此只需保留一。第二个和第三个对象仍然是相同的产品,但是来自不同的存储单元,因此在这种情况下,只需添加 gjendje 。最后,应该只有一个产品带有 KODARTIKULLI: SD13137 gjendje:1 + gjendje:1 = gjendje:2 )。相同的商品带有不同的



我尝试过的操作 >
我可以基于一个属性但不使用2个属性来删除重复项:

  //删除其自身的重复项,例如:仅保留一个基于KODARTIKULL 
函数的唯一对象removeDuplicates(originalArray,prop){
var newArray = [];
var lookupObject = {};

for(var in in originalArray){
lookupObject [originalArray [i] [prop]] = originalArray [i];
}

for(i在lookupObject中){
newArray.push(lookupObject [i]);
}
返回newArray;
}

对于 KODARTIKULLI,我都可以两次调用 KODI ,但这是行不通的,因为它只会根据我的条件继续删除产品。



我还尝试通过遍历整个数组来添加 gjendje 。因此,对于每种产品,我将从所有其他具有相同 KODARTIKULLI 的其他产品中添加 gjendje 。在此之后,我将调用上面的函数,并且由于所有相同的产品将具有相同的 gjendje ,因此我将删除所有重复项。但这也不起作用,因为有些产品来自同一存储单元,因为它们完全相同,因此只需要删除它们即可。

  //遍历数组
中的所有对象,用于(var i = 0; i< newArrMagGjendje.length; i ++){

//遍历所有我以外的对象
//不自动增加;我们稍后将在
中执行以下操作:(var j = i + 1; j< newArrMagGjendje.length; j ++){

//检查我们的x值是否匹配
如果(newArrMagGjendje [i] .KODARTIKULLI == newArrMagGjendje [j] .KODARTIKULLI){
newArrMagGjendje [i] .gjendje = newArrMagGjendje [i] .gjendje + newArrMagGjendje [j] .gjendje;
newArrayM.push(newArrMagGjendje [i]);
}
}
}

我知道这看起来有点很长的时间,但我目前仍处于困境,不知道如何以不同的方式解释它。
谢谢

解决方案

我认为您正在寻找 array.prototype.reduce ,这将允许您应用回调函数



此外,请阅读有关如何提供最小示例如果您有一个对象数组,那么它有一个实际的对象数组,而不是需要转换以创建工作示例的字符串,会有所帮助。 p>

编辑



在匹配的Kodartikulli键上添加第二个化简键以总计gjendje键,您可以使用一个化简键来完成此操作,但是(个人观点)我认为通常最好的做法是使您的职能范围狭窄。



  const data = [{BARKOD: Pa Detatime,DETAJIM1: ,DETAJIM2:,DTMODIFIKIM: 2017-10-02T16:06:53.206Z,KODARTIKULLI: SD13137,KODI: MX02,KODNJESIA1:应付,PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56 ,cmimibaze:0,gjendje:1,},{BARKOD: Pa Detatime,DETAJIM1:,DETAJIM2:,DTMODIFIKIM: 2017-10-02T16:06:53.206Z,KODARTIKULLI: SD13137, KODI: MX02,KODNJESIA1:应付,PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56,cmimibaze:0,gjendje:1,},{BARKOD: Pa Detatime,DETAJIM1:,DETAJIM2: ,DTMODIFIKIM: 2017-10-02T16:06:53.206Z,KODARTIKULLI: SD13137,KODI: MX03,KODNJESIA1:应付,PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56,cmimibaze:0,gjendje :1,},{BAR KOD: Pa Detatime,DETAJIM1:,DETAJIM2:,DTMODIFIKIM: 2017-10-02T16:06:53.206Z,KODARTIKULLI: SD13141,KODI: MX02,KODNJESIA1:应付, PERSHKRIMARTIKULLI: Emporio Armani 4097 5574 71 56,cmimibaze:0,gjendje:1,}]; const重复数据删除=(组,当前)=> {const index = group.findIndex(val =>(val.KODI == current.KODI& val.KODARTIKULLI == current.KODARTIKULLI));如果(index === -1){group.push(current); } return group;}; const totals =(group,current)=> {const index = group.findIndex(val => val.KODARTIKULLI == current.KODARTIKULLI); if(index === -1){return [... group,current]; } group [index] .gjendje + = current.gjendje; return group;}; const result = data.reduce(dedupe,[])。reduce(totals [[]); console.log(result);  


I have an array with objects like below.

0:Object
 BARKOD:"Pa Detatime"
 DETAJIM1:""
 DETAJIM2:""
 DTMODIFIKIM:"2017-10-02T16:06:53.206Z"
 KODARTIKULLI:"SD13137"
 KODI:"MX02"
 KODNJESIA1:"cope"
 PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56"
 cmimibaze:0
 gjendje:1
1:Object
 BARKOD:"Pa Detatime"
 DETAJIM1:""
 DETAJIM2:""
 DTMODIFIKIM:"2017-10-02T16:06:53.206Z"
 KODARTIKULLI:"SD13137"
 KODI:"MX02"
 KODNJESIA1:"cope"
 PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56"
 cmimibaze:0
 gjendje:1
2:Object
 BARKOD:"Pa Detatime"
 DETAJIM1:""
 DETAJIM2:""
 DTMODIFIKIM:"2017-10-02T16:06:53.206Z"
 KODARTIKULLI:"SD13137"
 KODI:"MX03"
 KODNJESIA1:"cope"
 PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56"
 cmimibaze:0
 gjendje:1
3:Object
 BARKOD:"Pa Detatime"
 DETAJIM1:""
 DETAJIM2:""
 DTMODIFIKIM:"2017-10-02T16:06:53.206Z"
 KODARTIKULLI:"SD13141"
 KODI:"MX02"
 KODNJESIA1:"cope"
 PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56"
 cmimibaze:0
 gjendje:1

Now I want to remove the duplicates using these 2 properties: "KODI" and "KODARTIKULLI", for example at the first 2 objects you can see that both "KODI" and "KODARTIKULLI" are the same so I want to keep only one.

And the second question which is more important and may even solve the first one. These objects are products that are taken from different storage units, ("KODI" represents the storage unit id). So what I want is for a unique product (product id is "KODARTIKULLI") to add all the available units (available units are stored in "gjendje"). This may seem a bit complicated but i want that the above array to look like below:

0:Object
 BARKOD:"Pa Detatime"
 DETAJIM1:""
 DETAJIM2:""
 DTMODIFIKIM:"2017-10-02T16:06:53.206Z"
 KODARTIKULLI:"SD13137"
 KODI:"MX02"
 KODNJESIA1:"cope"
 PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56"
 cmimibaze:0
 gjendje:2
1:Object
 BARKOD:"Pa Detatime"
 DETAJIM1:""
 DETAJIM2:""
 DTMODIFIKIM:"2017-10-02T16:06:53.206Z"
 KODARTIKULLI:"SD13141"
 KODI:"MX02"
 KODNJESIA1:"cope"
 PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56"
 cmimibaze:0
 gjendje:1

So since the first 2 objects are the same product and come from the same storage unit, to just keep one. And the second and third objects are still the same product but come from different storage units, so in this case just add "gjendje". In the end there should be just one product with KODARTIKULLI:"SD13137"and "gjendje:2" (gjendje:1+gjendje:1=gjendje:2). The same for products with different "KODARTIKULLI".

What I've tried: I can remove duplicates based on one property but not using 2 properties:

// Remove duplicates of it's own, ex: only keeps one unique object based on KODARTIKULL
function removeDuplicates(originalArray, prop) {
     var newArray = [];
     var lookupObject  = {};

     for(var i in originalArray) {
        lookupObject[originalArray[i][prop]] = originalArray[i];
     }

     for(i in lookupObject) {
         newArray.push(lookupObject[i]);
     }
      return newArray;
 }

I can call this twice for both "KODARTIKULLI" and "KODI" but that won't work because it will just keep removing products not based on my conditions.

I also tried to add "gjendje" by looping through the whole array. So for each product I'll add the "gjendje" from all the other products with the same "KODARTIKULLI". After this then I'd call the above function and since all the same products would have the same "gjendje", I'd just remove all the duplicates. But this also doesn't work because there are some products that come from the same storage unit which need to just be removed because are exactly the same.

  // Loop through all objects in the array
  for (var i = 0; i < newArrMagGjendje.length; i++) {

    // Loop through all of the objects beyond i
    // Don't increment automatically; we will do this later
    for (var j = i+1; j < newArrMagGjendje.length;j++ ) {

      // Check if our x values are a match
      if (newArrMagGjendje[i].KODARTIKULLI == newArrMagGjendje[j].KODARTIKULLI) {
        newArrMagGjendje[i].gjendje=newArrMagGjendje[i].gjendje+newArrMagGjendje[j].gjendje;
        newArrayM.push( newArrMagGjendje[i]);
      } 
    }
  }

I know it looks a bit long, but I'm stuck at the moment and didn't know how to explain it differently. Thank you

解决方案

I think you are looking for array.prototype.reduce, that will allow you to apply a callback function to your array to output a new array matching the functions output criteria.

As an aside, please read up on how to provide a minimal example if you have an array of objects it helps to have an actual array of objects and not a string that needs to be converted in order to create a working example.

Edit

Added a second reducer to total the gjendje key on matched Kodartikulli keys, you could do this with one reducer, but (personal opinion) I think it is generally a better practice to keep your functions narrow in scope.

const data = [
  {
    BARKOD:"Pa Detatime",
    DETAJIM1:"",
    DETAJIM2:"",
    DTMODIFIKIM:"2017-10-02T16:06:53.206Z",
    KODARTIKULLI:"SD13137",
    KODI:"MX02",
    KODNJESIA1:"cope",
    PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56",
    cmimibaze:0,
    gjendje:1,
  },
  {
    BARKOD:"Pa Detatime",
    DETAJIM1:"",
    DETAJIM2:"",
    DTMODIFIKIM:"2017-10-02T16:06:53.206Z",
    KODARTIKULLI:"SD13137",
    KODI:"MX02",
    KODNJESIA1:"cope",
    PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56",
    cmimibaze:0,
    gjendje:1,
  },
  {
    BARKOD:"Pa Detatime",
    DETAJIM1:"",
    DETAJIM2:"",
    DTMODIFIKIM:"2017-10-02T16:06:53.206Z",
    KODARTIKULLI:"SD13137",
    KODI:"MX03",
    KODNJESIA1:"cope",
    PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56",
    cmimibaze:0,
    gjendje:1,
  },
  {
    BARKOD:"Pa Detatime",
    DETAJIM1:"",
    DETAJIM2:"",
    DTMODIFIKIM:"2017-10-02T16:06:53.206Z",
    KODARTIKULLI:"SD13141",
    KODI:"MX02",
    KODNJESIA1:"cope",
    PERSHKRIMARTIKULLI:"Emporio Armani 4097 5574 71 56",
    cmimibaze:0,
    gjendje:1,
  }
];

const dedupe = (group, current) => {
  const index = group.findIndex(val => (val.KODI == current.KODI && val.KODARTIKULLI == current.KODARTIKULLI));
  if (index === -1) {
    group.push(current);
  }
  return group;
};
const totals = (group, current) => {
  const index = group.findIndex(val => val.KODARTIKULLI == current.KODARTIKULLI);
  if (index === -1) {
    return [ ...group, current];
  }

  group[index].gjendje += current.gjendje;
  return group;
};

const result = data.reduce(dedupe, []).reduce(totals, []);
console.log(result);

这篇关于遍历对象数组并根据属性添加它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆