如果不存在于另一个数组中,如何删除数组中的对象

时间:2018-11-15 16:48:29

标签: javascript arrays

如果另一个数组中不存在对象,我想删除该对象。 我试图搜索并在此link中找到了类似的问题,但是有不同的数组源。

这是上面链接中的示例:

var check = [1, 2, 3];
var allowed = [1];

var filtered = check.filter(function(item) {
  return allowed.indexOf(item) > -1;
});

console.log(filtered);

上面的示例删除数组check中不存在的数组allowed中的数字。就我而言,源数组包含一个类似于下面示例的对象:

var check = [
    {
        name: 'Peter',
        location: 'florida'
    },
    {
        name: 'Robert',
        location: 'California'
    }
];

var allowed = [
    {
        name: 'Robert',
        location: 'Boston'
    }
];

var filtered = check.filter(function(item) {
  return allowed.indexOf(item.name) > -1;
});

console.log(filtered);

我试图运行代码,结果是一个空数组。

我期望的结果:

[
    {
        name: 'Robert',
        location: 'California'
    }
]

任何人都可以帮助我取得我所期望的结果吗?

5 个答案:

答案 0 :(得分:4)

您可以使用Array#find()

var check = [{
    name: 'Peter',
    location: 'florida'
  },
  {
    name: 'Robert',
    location: 'California'
  }
];

var allowed = [{
  name: 'Robert',
  location: 'Boston'
}];

var res = check.filter(function(cItem) {
  return allowed.find(function(aItem) {
    return cItem.name === aItem.name
  })
})

console.log(res)

答案 1 :(得分:3)

您可以将allowed映射为仅包含您要查找的条件(名称):

var allowed = [{
    name: 'Robert',
    location: 'Boston'
}]
.map(obj => obj.name);

这将创建一个仅包含名称的数组,从而更易于测试indexOf

示例:

var check = [{
    name: 'Peter',
    location: 'florida'
  },
  {
    name: 'Robert',
    location: 'California'
  }
];

var allowed = [{
  name: 'Robert',
  location: 'Boston'
}]
.map(obj => obj.name);

var filtered = check.filter(function(item) {
  return allowed.indexOf(item.name) > -1;
});

console.log(filtered);

答案 2 :(得分:1)

您需要检查allowed数组中的项目名称。 现在,您正在检查允许的数组中的项目,该类型是一个对象。

问题出在这里:return allowed.indexOf(item.name) > -1;

也许这种方法有帮助:

var check = [
    {
        name: 'Peter',
        location: 'florida'
    },
    {
        name: 'Robert',
        location: 'California'
    }
];

var allowed = [
    {
        name: 'Robert',
        location: 'Boston'
    }
];

function containsName(name, array){
  return array.find(item => item.name === name);
}

var filtered = check.filter(function(item) {
  return containsName(item.name, allowed)
});

console.log(filtered);

答案 3 :(得分:1)

以下相交函数将与任何给定对象数组上的任何键相交:

var check = [
    { name:'Peter', location:'florida' },
    { name:'Robert', location:'California'}
];

var allowed = [
    { name:'Robert', location:'Boston' }
];

function intersect(check, allowed) {
    var allowed_map = allowed.reduce(function(map, obj) {
        Object.keys(obj).forEach(function(key) {
            if (!map[key]) {
                map[key] = [];
            }
            map[key].push(obj[key]);
        });
        return map;
    }, {});


    return check.filter(function(item) {
        return Object.keys(item).find(function(key) {
            return allowed_map[key].indexOf(item[key]) != -1;
        })
    });
}

var filtered = intersect(check, allowed);

var allowed2 = [{ name:'Bob', location:'California' }];
var filtered2 = intersect(check, allowed2);

console.log('filtered',filtered);
console.log('filtered2',filtered2);

答案 4 :(得分:1)

有多种方法可供您选择。

  • 脏支票
  • 特定属性检查
  • 嵌套对象检查

脏支票

要仔细检查对象在两个阵列上具有相同的内存引用,可以执行以下操作。

var firstPerson = {
    name: 'Peter',
    location: 'florida'
}
var secondPerson = {
    name: 'Robert',
    location: 'California'
}

var allowed = [secondPerson];
var check = [firstPerson, secondPerson];

var result = check.filter(item => allowed.includes(item));

console.log(result);

特定属性检查

对于特定属性检查,您可以使用find并通过checkallowed之类的属性比较namelocation

var check = [
    {
        name: 'Peter',
        location: 'florida'
    },
    {
        name: 'Robert',
        location: 'California'
    }
];

var allowed = [
    {
        name: 'Robert',
        location: 'Boston'
    }
];


var result = check.filter(checkPerson => allowed.find(allowPerson => allowPerson.name === checkPerson.name));

console.log(result);

嵌套对象检查

对于嵌套对象检查,您需要递归地检查项目,我使用了我前一段时间创建的名为deepCompare的实用程序,它是Lodash的isEqual的替代方法,后者仅重880B

var check = [
    {
        name: 'Peter',
        location: {
            street: "fridtjof nansens vei 8511",
            city: "ågotnes",
            state: "buskerud",
            postcode: "8766",
            coordinates: {
                latitude: "50.4828",
                longitude: "-84.6920"
            }
        }
    },
    {
        name: 'Robert',
        location: {
            street: "schillerstraße 69",
            city: "velburg",
            state: "saarland",
            postcode: 72100,
            coordinates: {
                latitude: "30.4655",
                longitude: "9.1938"
            }
        }
    }
];

var allowed = [
    {
        name: 'Robert',
        location: {
            street: "schillerstraße 69",
            city: "velburg",
            state: "saarland",
            postcode: 72100,
            coordinates: {
                latitude: "30.4655",
                longitude: "9.1938"
            }
        }
    }
];


var result = check.filter(checkPerson => allowed.some(allowPerson => deepCompare(checkPerson, allowPerson)));

console.log(result);
<script>
/**
 * Deep Compare
 * @param { * } value first entry value
 * @param { * } other second entry value
 * @param { Boolean } sorted Sort any array before deep comparison
 */
const deepCompare = (value, other, sorted) => {
  /**
   * Compare possible primitives
   * Object.is works like `===` but additionally differes positive from negative values
   * I.E:
   *  Object.is(-0, 0) // False
   *  -0 === 0 // True
   */
  if (Object.is(value, other)) return true;
  /**
   * Check if either value is undefined or the constructor is different for each value
   * given the case return false
   */
  if (!value || !other || value.constructor !== other.constructor) return false;
  /**
   * Check Object and Array deep comparisons
   */
  switch (value.constructor) {
    case Array:
      /**
       * Check if both values have the same amount of items
       * if they don't immediatelly omit the comparison and return false
       */
      if (value.length === other.length) { return deepArrayCompare(value, other, sorted); }
      return false;
    case Object:
      /**
       * Check if both values have the same amount of keys
       * if they don't immediatelly omit the comparison and return false
       */
      if (Object.keys(value).length === Object.keys(other).length) { return deepObjectCompare(value, other, sorted); }
      return false;
  }
  return false;
};
/**
 * Deep Object Compare
 * @param { * } value first entry value
 * @param { * } other second entry value
 *
 * 'deepArrayCompare(Object.keys(value), Object.keys(other), sorted)'
 * This checks that both objects have the same keys
 * I.E:
 *  deepArrayCompare(Object.keys({ a: 1, b: 2, c:3 }), Object.keys({ a: 10, b: 22, c: 54 }), true) // True
 *  deepArrayCompare(Object.keys({ a: 1, b: 2, c:3 }), Object.keys({ g: 1, f: 2, d: 3 }), true) // False
 *
 * 'Object.keys(value).every(key => deepCompare(value[key], other[key]))'
 * This iterates on each key of the object over a 'every' comparison and performs a deepCompare on both values
 *
 */
const deepObjectCompare = (value, other) => deepArrayCompare(Object.keys(value), Object.keys(other), true) && Object.keys(value).every(key => deepCompare(value[key], other[key]));
/**
 * Deep Array Compare
 * @param { * } value first entry value
 * @param { * } other second entry value
 * @param { Boolean } sorted Sort any array before deep comparison
 *
 * '(sorted && value.sort(), sorted && other.sort(), ...)'
 * This manages the optional sorting through Comma Operator
 *
 * 'value.every((item, index) => deepCompare(item, other[index]))'
 * This performs the deepComparison of values between both arrays
 */
const deepArrayCompare = (value, other, sorted) => (sorted && value.sort(), sorted && other.sort(), value.every((item, index) => deepCompare(item, other[index])));
</script>