基于多个属性过滤对象数组

时间:2018-03-08 18:41:22

标签: javascript arrays node.js filter

TL;博士

我试图重复删除不一定相同的对象数组。

递减。

我从一个管理它们的网站上下载了一组记录,并且有许多重复的记录,尽管有些记录具有不同的名称或不同的权重。 id喜欢做的是将每个记录与另一个记录进行比较并删除所有条目,但是除了一个具有最大权重的条目,或者除了一个条目之外的所有条目都存在完全重复(包括名称)。

Arr obj

{
      "entry"   : "Single Lift",
      "name"    : "Jane Doe",
      "sex"     : "female",
      "division": "40-44",
      "equipped": "raw",
      "wtclass" : 66,
      "lift"    : "bench press",
      "weight"  : 151
  }

function dedupe(lift=records){
    console.log(lift.length)
    lift.forEach((record,index)=>{
      for(i=0;i<lift.length;i++){
        if(record.sex===lift[i].sex){
          if(record.division===lift[i].division){
            if(record.equipped===lift[i].equipped){
              if(record.wtclass===lift[i].wtclass){
                if(record.entry===lift[i].entry){
                  if(record.name===lift[i].name&&record.weight===lift[i].weight) lift.splice(i,1)
                  else if(record.weight>lift[i].weight) lift.splice(i,1)
                  else if(record.weight<lift[i].weight) lift.splice(index,1)
                }
              }
            }
          }
        }
      }
    })
    console.log(lift.length)
    return lift
  }

这段代码显然没有按照我想要的方式运行,但它说明了意图。我想通过比较entry sex division {{1} equipped wtclass lift {{1}} {{1}} {{1}} {{1}} {{1}} {{1}} {{1}} {{1}} {{1}} {{1}} {{1}} {{1}} } {{1}}和{{1}}是匹配。

关于重复删除对象数组还有其他问题,但我找不到与我的场景相匹配的任何内容,或者我能够适应我的工作。如果有人有解决方案(或解决方案的链接),我将非常感激!

3 个答案:

答案 0 :(得分:2)

使用这些值,您可以连接它们并检查重复项。

您可以使用reduce功能。

此示例有两个具有相同值(但权重)的对象,其中一个具有不同的值。

var array = [
  {
    'entry': 'Single Lift',
    'name': 'Jane Doe',
    'g': 'f',
    'division': '40-44',
    'equipped': 'raw',
    'wtclass': 66,
    'lift':
    'bench press', 'weight': 151
  },
  {
    'entry': 'Single Lift',
    'name': 'Jane Doe',
    'g': 'f',
    'division': '40-44',
    'equipped': 'raw',
    'wtclass': 66,
    'lift': 'bench press',
    'weight': 160
  },
  {
    'entry': 'Single Lift', 
    'name': 'Ele', 
    'g': 'm', 
    'division': '40-44', 
    'equipped': 'raw', 
    'wtclass': 66, 
    'lift': 'bench press', 
    'weight': 151
  }
]

var result = Object.values(array.reduce((a, o) => {
  var {
    entry, 
    name, 
    g, 
    division, 
    equipped, 
    wtclass, lift
  } = o
  
  var key = [
    entry, 
    name, 
    g, 
    division, 
    equipped, 
    wtclass, 
    lift
  ].join('||')

  if (!a[key] || o.weight > a[key].weight) {
    a[key] = o
  }

  return a
}, {}))

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

const array = [
  { "entry"   : "Single Lift", "name"    : "Jane Doe", "sex"     : "female", "division": "40-44", "equipped": "raw", "wtclass" : 66, "lift"    : "bench press", "weight"  : 151 }, { "entry"   : "Single Lift", "name"    : "Jane Doe", "sex"     : "female", "division": "40-44", "equipped": "raw", "wtclass" : 66, "lift"    : "bench press", "weight"  : 152 }, { "entry"   : "Single Lift", "name"    : "Jane Doe", "sex"     : "female", "division": "40-44", "equipped": "raw", "wtclass" : 66, "lift"    : "bench press", "weight"  : 151 }, { "entry"   : "Double Lift", "name"    : "Jane Doe", "sex"     : "female", "division": "40-44", "equipped": "raw", "wtclass" : 66, "lift"    : "bench press", "weight"  : 151 }
]

const groupBy = (xs, exceptions) => 
   xs.reduce((groups, element) => {
     var key = Object.assign({}, element);
     for (let i = 0; i < exceptions.length; i++) {
       delete key[exceptions[i]];
     }
     key = Object.values(key).join(',');
           
     if (!groups[key]) {
        groups[key] = [element];
     } else {
        groups[key].push(element);
     }

     return groups;
   }, {})

let grouppedRecords = groupBy(array, ['weight']);

let biggestWeightRecords = Object.values(grouppedRecords).map(records => {
  let biggestWeightRecord = records[0];
  for (let i = 0; i < records.length; i++) {
    if (records[i].weight > biggestWeightRecord.weight) {
      biggestWeightRecord = records[i];
    }
  }
  return biggestWeightRecord;
});

console.log(biggestWeightRecords);

答案 2 :(得分:0)

具有2次迭代的解决方案,允许过滤任意数量的属性,两个规则(更大和更小),只有在过滤器属性的值是原始值时才有效。

const elements = [
    {
        foo: 1,
        bar: 2,
        fooBard: 3,
    },
    {
        foo: 2,
        bar: 2,
        fooBard: 6,
    },
    {
        foo: 1,
        bar: 2,
        fooBard: 5,
    },
    {
        foo: 2,
        bar: 2,
        fooBard: 3,
    }
];

const RULE_BIGGER = 'RULE_BIGGER';
const RULE_SMALLER = 'RULE_SMALLER';

const elementsFiltered = new Map();

const createKey = (element, ...matchingProperties) =>
    matchingProperties
    .map(matchProperty => element[matchProperty] || '')
    .join('#');


const hasToBeUpdated = (rule) => (oldValue, newValue) => {
    switch (rule) {
        case RULE_BIGGER:
            return newValue > oldValue;
        case RULE_SMALLER:
            return newValue < oldValue;
        default:
            return false;
    }
}

const filterByProperty = (elements, property, rule, ...matchingProperties) => {
    const hasToBeUpdatedWithRule = hasToBeUpdated(rule);
    elements.forEach((element) => {
        const key = createKey(element, ...matchingProperties);
        const storedElement = elementsFiltered.get(key)
        if (!storedElement ||
            hasToBeUpdatedWithRule(storedElement[property], element[property])) {
                elementsFiltered.set(key, element);
        }
    });
    const result = [];
    elementsFiltered.forEach(elementFiltered => {
        result.push(elementFiltered);
    });
    return result;
};

const result = filterByProperty(elements, 'fooBard', RULE_BIGGER, 'foo', 'bar');

console.log(result);