Фильтровать массив объектов на основе содержимого другого массива вложенных объектов. - PullRequest
0 голосов
/ 12 апреля 2019

Я хочу отфильтровать массив positions и удалить все позиции, представленные в массиве people.

Я пробовал несколько комбинаций _.forEach и _.filter, но просто не могу понять это.

console.log(position)

var test = _.filter(position, function(pos) {
    _.forEach(people, function(peo) {
        _.forEach(peo.position, function(peoplePos) {
            if(peoplePos.value == pos.value){
                return false;
            }
        });
    });
});

console.log(test)

Моя главная проблема, я думаю, заключается впозиции вложены в каждый объект людей

var positions = [{
    val: 'CEO',
    label: 'CEO XXX'
}, {
    val: 'CTO',
    label: 'CTO XXX'
}, {
    val: 'CBO',
    label: 'CBO XXX'
}, {
    val: 'CLO',
    label: 'CLO XXX'
}]

var people = [{
    id: 'AAA',
    positions: [{
        val: 'CEO',
        label: 'CEO XXX'
    }]
},{
    id: 'BBB',
    positions: [{
        val: 'CXO',
        label: 'CXO XXX'
    },{
        val: 'CEO',
        label: 'CEO XXX'
    }]
},{
    id: 'CCC',
    positions: [{
        val: 'CTO',
        label: 'CTO XXX'
    }]
}]

В этом сценарии я стремлюсь к следующему результату:

var positions = [{
    val: 'CBO',
    label: 'CBO XXX'
}, {
    val: 'CLO',
    label: 'CLO XXX'
}]

Поскольку CBO и CLO не представлены ни одним объектом вмассив людей.

Ответы [ 3 ]

1 голос
/ 12 апреля 2019

Вы можете использовать filter, find и some, чтобы отфильтровать те объекты, которые не появляются в массиве положений из массива людей.

var positions = [{val:'CEO',label:'CEOXXX'},{val:'CTO',label:'CTOXXX'},{val:'CBO',label:'CBOXXX'},{val:'CLO',label:'CLOXXX'}];
var people = [{id:'AAA',positions:[{val:'CEO',label:'CEOXXX'}]},{id:'BBB',positions:[{val:'CXO',label:'CXOXXX'},{val:'CEO',label:'CEOXXX'}]},{id:'CCC',positions:[{val:'CTO',label:'CTOXXX'}]}];

const out = positions.filter(position => {
  return !people.find(person => {
    return person.positions.some(({ val, label }) => {
      return val === position.val && label === position.label;
    });
  });
});

console.log(out);
1 голос
/ 12 апреля 2019

Реализация моего комментария.

Все это можно записать в виде большого .reduce() в массиве позиций, чтобы сделать его более эффективным, но я предпочел показать точные шаги, чтобы было более понятно, что делает каждый шаг.

var positions = [{val:'CEO',label:'CEOXXX'},{val:'CTO',label:'CTOXXX'},{val:'CBO',label:'CBOXXX'},{val:'CLO',label:'CLOXXX'}];

var people = [{id:'AAA',positions:[{val:'CEO',label:'CEOXXX'}]},{id:'BBB',positions:[{val:'CXO',label:'CXOXXX'},{val:'CEO',label:'CEOXXX'}]},{id:'CCC',positions:[{val:'CTO',label:'CTOXXX'}]}];

const occupied_positions = people
  .map( person => person.positions )
  .flat()
  .map( position => position.val );
  
const all_positions = positions
  .map( position => position.val );
  
const open_positions = all_positions
  .filter( position => !occupied_positions.includes( position ))
  .map( position => positions.find( source => source.val === position ));
  
console.log( open_positions );
1 голос
/ 12 апреля 2019

Быстрый способ состоит в том, чтобы структурировать массив people и проверить позицию в строке.

Это избавляет вас от необходимости проходить через вложенную структуру.

var positions = [{ val: 'CEO', label: 'CEO XXX' }, { val: 'CTO', label: 'CTO XXX' }, { val: 'CBO', label: 'CBO XXX' }, { val: 'CLO', label: 'CLO XXX' }]

var people = [{ id: 'AAA', positions: [{ val: 'CEO', label: 'CEO XXX' }] }, { id: 'BBB', positions: [{ val: 'CXO', label: 'CXO XXX' }, { val: 'CEO',
    label: 'CEO XXX' }] }, { id: 'CCC', positions: [{ val: 'CTO', label: 'CTO XXX' }] }];

var stringifiedPeople = JSON.stringify(people)

var newPositions = positions.filter((position) =>
  !stringifiedPeople.includes(JSON.stringify(position))
);

console.log(newPositions)

Или вы можете создать карту, которая будет содержать все занятые позиции и отфильтровать доступные позиции.

var positions = [{ val: 'CEO', label: 'CEO XXX' }, { val: 'CTO', label: 'CTO XXX' }, { val: 'CBO', label: 'CBO XXX' }, { val: 'CLO', label: 'CLO XXX' }]

var people = [{ id: 'AAA', positions: [{ val: 'CEO', label: 'CEO XXX' }] }, { id: 'BBB', positions: [{ val: 'CXO', label: 'CXO XXX' }, { val: 'CEO',
    label: 'CEO XXX' }] }, { id: 'CCC', positions: [{ val: 'CTO', label: 'CTO XXX' }] }];

var mappedPositions = {}

people.forEach((p) =>
  p.positions.forEach((position) =>
    mappedPositions[position.val] = true
  )
);

var newPositions = positions.filter((position) => !mappedPositions[position.val]);

console.log(newPositions)
...