循环遍历对象数组并根据属性

时间:2017-11-01 11:54:42

标签: javascript arrays object

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

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

现在我想使用这两个属性删除重复项:"KODI""KODARTIKULLI",例如,在前2个对象中,您可以看到"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:"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

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

的产品,情况相同

我尝试了什么: 我可以根据一个属性删除重复项,但不使用2个属性:

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

我可以同时为"KODARTIKULLI""KODI"拨打两次电话,但这不会有效,因为它会继续根据我的条件删除产品。

我还尝试通过遍历整个数组来添加"gjendje"。因此,对于每个产品,我都会添加"gjendje"来自所有其他产品"KODARTIKULLI"的{​​{1}}。在此之后,我将调用上述功能,因为所有相同的产品都具有相同的"gjendje",我只需删除所有重复项。但这也不起作用,因为有些产品来自同一个存储单元需要被删除,因为它们完全相同。

  // 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]);
      } 
    }
  }

我知道它看起来有点长,但我现在卡住了,并且不知道如何以不同的方式解释它。 谢谢

4 个答案:

答案 0 :(得分:0)

function removeDuplicates(arr) {
    console.log("original length: "+arr.length);
    for (var i=0; i<arr.length; i++) {
        var listI = arr[i];
        loopJ: for (var j=0; j<arr.length; j++) {
            var listJ = arr[j];
            if (listI === listJ) continue; //Ignore itself
            for (var k=listJ.length; k>=0; k--) {
                if (JSON.stringify(listJ[k]) !== JSON.stringify(listI[k])) continue loopJ;
            }// At this point, their values are equal.

            arr.splice(j--, 1);
        }
    }
    console.log("length without duplicates: "+arr.length);
    return arr;
}

这是我写回来删除数组中任何重复对象的函数。由于您只想应用于两个属性,因此我们需要做的就是删除第三个循环,而只是检查这两个属性。

另请注意,有比JSON.stringify更好的比较对象的方法,但我不需要效率,我不知道你是否就是这种情况。

为您的目的修改代码:

function removeDuplicates(arr) {
    console.log("original length: "+arr.length);
    for (var i=0; i<arr.length; i++) {
        var listI = arr[i];
        loopJ: for (var j=0; j<arr.length; j++) {
            var listJ = arr[j];
            if (listI === listJ) continue; //Ignore itself
            if (JSON.stringify(listJ.KODI) !== JSON.stringify(listI.KODI)) {
                continue loopJ;
            }
            if (JSON.stringify(listJ.KODNJESIA1) !== JSON.stringify(listI.KODNJESIA1)) {
                continue loopJ;
            }      
            arr.splice(j--, 1);
        }
    }
    console.log("length without duplicates: "+arr.length);
    return arr;
}

我希望这就是你要找的东西

答案 1 :(得分:0)

基于2个属性进行过滤的简单方法是创建一个临时哈希对象,该对象使用这两个属性的组合值作为键。

var data = [{
  key1: 'A',
  key2: 1
}, {
  key1: 'A',
  key2: 1
}, {
  key1: 'B',
  key2: 1
}];
var tmp = {};

var res = data.filter(function(item) {
  // use a separator for the values to prevent possible collisions and prevent adding numbers 
  var combined = item.key1 + '|' +  item.key2,
     isUnique = !tmp[combined];
  if (isUnique) {
    tmp[combined] = true;    
  }  
  return isUnique;

});

console.log(res)

问题的第二部分有点不清楚

答案 2 :(得分:0)

我认为您正在寻找array.prototype.reduce,这将允许您将回调函数应用于您的数组,以输出与函数输出条件匹配的新数组。

顺便说一句,请阅读如何提供minimal example,如果你有一个对象数组,它有助于拥有一个实际的对象数组而不是一个需要转换的字符串,以便创建一个工作实例。

修改

添加了第二个减速器来匹配匹配的Kodartikulli键上的gjendje键,你可以用一个减速器完成这个,但是(个人意见)我认为保持你的功能通常是一个更好的做法在适用范围。

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

答案 3 :(得分:0)

首先获取基于KODARTIKULLI的唯一记录,并将存储单元添加到该唯一记录中。

var array = [{
 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
}];

这里添加了新属性以将所有KODI信息存储为数组

function addStorage(arr,hash,index,sd){
 var item = hash[index];
  if(item.SD.indexOf(sd) === -1){
    item.SD.push(sd);
  }
  arr[item.index].StorageUnit = item.SD;
  arr[item.index].gjendje = item.SD.length;
}

getUnique方法将删除基于KODARTIKULLI的副本,并将具有不同存储的记录添加到唯一记录

function getUnique(arr) {
  var hash = [];
  var storageHash = [];
  var length = arr.length,index = 0;
  for (; index < length;) {
    var item = arr[index];
    var key = item.KODARTIKULLI;    
    if (hash[key] !== undefined)
    {      
      addStorage(arr,hash,key,item.KODI);
      arr.splice(index, 1);
      index--;
      length--;
    } else {      
      hash[key] = {
         index:index,
         SD:[item.KODI]
      }
    }
    index++;
  }
  return arr;
}
console.log(getUnique(array));