фильтр внутри forEach не работает должным образом, когда находит двойные объекты - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь получить каждый объект массива и сравнить его с объектами другого массива.Если они совпадают, удалите объект из второго массива.

Странно то, что если объект обнаружен в массиве два раза, этот объект не фильтруется.

Я хочу сравнить newdata с existing.Если объект newdata имеет одинаковые id и cat, он не будет в новом массиве.

existing равно

var existing = [{
    name: "John",
    values_: {
      id: 5,
      cat: true
    }
  },
  {name: "Jake",
    values_: {
      id: 3,
      cat: true
    }
  },
  {
    name: "Alice",
    values_: {
      id: 2,
      cat: false
    }
  }
];

newdata равно

var newdata = [{
    name: "Mike",
    properties: {
      id: 1,
      cat: true
    }
  },
  {name: "Jake",
    properties: {
      id: 3,
      cat: true
    }
  },
  {name: "Jake",
    properties: {
      id: 3,
      cat: true
    }
  },
  {
    name: "Alice",
    properties: {
      id: 2,
      cat: false
    }
  }
];

, а мой фильтр

existing.forEach((existingitem, existingindex, existingfeatures) => {
  newdata2 = newdata.filter(item => (
    existingitem.values_.id != item.properties.id && 
    existingitem.values_.cat != item.properties.cat 

  ));
});

console.log('newdata2  - ',newdata2);

Логикаnewdata2 иметь только Mike.Проблема в том, что я вижу Jake два раза.Jake не должно быть там, оно уже в existing.

Если я отредактирую newdata примерно так (без двойных чисел)

var newdata = [{
    name: "Mike",
    properties: {
      id: 1,
      cat: true
    }
  },
  {name: "Jake",
    properties: {
      id: 3,
      cat: true
    }
  } ,
  {
    name: "Alice",
    properties: {
      id: 2,
      cat: false
    }
  }
];

Я все еще вижу Jake в newdata2.Но почему?

Пожалуйста, помогите мне исправить это.Это мой фильтр или способ filter работает?Исходя из критериев, я должен получить только Mike в конце.Пожалуйста, совет.

Спасибо

    var existing = [{
        name: "John",
        values_: {
          id: 5,
          cat: true
        }
      },
      {name: "Jake",
        values_: {
          id: 3,
          cat: true
        }
      },
      {
        name: "Alice",
        values_: {
          id: 2,
          cat: false
        }
      }
    ]; 

    var newdata = [{
        name: "Mike",
        properties: {
          id: 1,
          cat: true
        }
      },
      {name: "Jake",
        properties: {
          id: 3,
          cat: true
        }
      },
      {name: "Jake",
        properties: {
          id: 3,
          cat: true
        }
      },
      {
        name: "Alice",
        properties: {
          id: 2,
          cat: false
        }
      }
    ];
 

    existing.forEach((existingitem, existingindex, existingfeatures) => {
      newdata2 = newdata.filter(item => (
        existingitem.values_.id != item.properties.id && 
        existingitem.values_.cat != item.properties.cat 
    
      ));
    });
    
    console.log('newdata2  - ',newdata2);

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

... подумайте о filter (внешнем) и every (внутреннем) подходе вместо forEach и filter - возможно, это облегчит думать о правильной реализации.

var existingItemList = [{ name: "John", values_: { id: 5, cat: true }}, { name: "Jake", values_: { id: 3, cat: true }}, { name: "Alice", values_: { id: 2, cat: false }}];
var newItemList = [{ name: "Mike", properties: { id: 1, cat: true }}, { name: "Jake", properties: { id: 3, cat: true }}, { name: "Jake", properties: { id: 3, cat: true }}, { name: "Alice", properties: { id: 2, cat: false }}];

var itemList = newItemList.filter(function (newItem) {    // filter `newItem` only
  return existingItemList.every(function (existingItem) { // if it does not exist
    return (                                              // in `existingItemList`.
    //(newItem.name !== existingItem.name) &&
      (newItem.properties.id !== existingItem.values_.id)
    );
  });
});

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

РЕДАКТИРОВАТЬ

продолжить, ссылаясь на мой комментарий ...

ваше условие сравнения просто не соответствует тому, что вы действительно ищете / ищете.

Если все еще предполагается, что ОП хочет отфильтровать новый элемент, только если он этого не делаетуже существует в другом списке, который будет сравниваться с ...

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

Этот компаратор / сопоставитель затем должен использоваться таким образом, чтобы он фильтровал только тот самый новый элемент, который не равен ни одному другому уже существующему элементу.

Это может быть достигнуто путем небольшого изменения прежнего подходасверху ...

function doesExistingItemMatchBoundNewItem(existingItem) {
  var newItem = this;
  return (
       (newItem.properties.id === existingItem.values_.id)
    && (newItem.properties.cat === existingItem.values_.cat)
  );
}

var existingItemList = [{ name: "John", values_: { id: 5, cat: true }}, { name: "Jake", values_: { id: 3, cat: true }}, { name: "Alice", values_: { id: 2, cat: false }}];
var newItemList = [{ name: "Mike", properties: { id: 1, cat: true }}, { name: "Jake", properties: { id: 3, cat: true }}, { name: "Jake", properties: { id: 3, cat: true }}, { name: "Alice", properties: { id: 2, cat: false }}];

var itemList = newItemList.filter(function (newItem) {
  return !existingItemList.some(doesExistingItemMatchBoundNewItem.bind(newItem));
});

console.log('itemList : ', itemList);
.as-console-wrapper { max-height: 100%!important; top: 0; }
0 голосов
/ 05 декабря 2018

Вы можете взять Set и отфильтровать известные предметы.

var existing = [{ name: "John", values_: { id: 5, cat: true } }, { name: "Jake", values_: { id: 3, cat: true } }, { name: "Alice", values_: { id: 2, cat: false } }],
    newdata = [{ name: "Mike", properties: { id: 1, cat: true } }, { name: "Jake", properties: { id: 3, cat: true } }, { name: "Jake", properties: { id: 3, cat: true } }, { name: "Alice", properties: { id: 2, cat: false } }],
    eSet = new Set(existing.map(({ values_: { id, cat } }) => [id, cat].join('|'))),
    result = newdata.filter(({ properties: { id, cat } }) => !eSet.has([id, cat].join('|')));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...