获取具有多个约束的两个对象数组的差

时间:2019-05-31 15:33:01

标签: javascript

我试图通过应用多个AND约束来获得两个对象数组的差。

在这里找到一个小例子:

const dbArr = [{
    name: 'Company1',
    symbol: 'C1',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company2',
    symbol: 'C2',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company3',
    symbol: 'C3',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company4',
    symbol: 'C4',
    ratingID: '1',
    stockID: '2'
  },
]

const diffArr = [{
    name: 'Company1',
    symbol: 'C1',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company6',
    symbol: 'C6',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company1',
    symbol: 'C1',
    ratingID: '5',
    stockID: '3'
  },
  {
    name: 'Company10',
    symbol: 'C10',
    ratingID: '1',
    stockID: '2'
  },
]

const res = diffArr.filter(cv => !dbArr.find(e => e.name === cv.name)).filter(cv => !dbArr.find(e => e.ratingID === cv.ratingID)).filter(cv => !dbArr.find(e => e.stockID === cv.stockID))

console.log(res)


/* 
RESULT I would like to get:

const dbArr = [{
  name: 'Company1',
  symbol: 'C1',
  ratingID: '1',
  stockID: '2'
},
{
  name: 'Company2',
  symbol: 'C2',
  ratingID: '1',
  stockID: '2'
},
{
  name: 'Company3',
  symbol: 'C3',
  ratingID: '1',
  stockID: '2'
},
{
  name: 'Company4',
  symbol: 'C4',
  ratingID: '1',
  stockID: '2'
},
{
  name: 'Company6',
  symbol: 'C6',
  ratingID: '1',
  stockID: '2'
},
{
  name: 'Company1',
  symbol: 'C1',
  ratingID: '5',
  stockID: '3'
},
{
  name: 'Company10',
  symbol: 'C10',
  ratingID: '1',
  stockID: '2'
},
] */

最终结果是,我尝试连接多个finds,但是得到一个空数组。

但是,如果我只使用一次find,我的方法就会起作用。

有人建议我在做什么错吗?

3 个答案:

答案 0 :(得分:3)

当您链接多个.filter时,实际上是在说只返回满足 all 条件的元素;而您期望的数组包含满足任何个比较条件的元素。

const dbArr = [{
    name: 'Company1',
    symbol: 'C1',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company2',
    symbol: 'C2',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company3',
    symbol: 'C3',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company4',
    symbol: 'C4',
    ratingID: '1',
    stockID: '2'
  },
]

const diffArr = [{
    name: 'Company1',
    symbol: 'C1',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company6',
    symbol: 'C6',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company1',
    symbol: 'C1',
    ratingID: '5',
    stockID: '3'
  },
  {
    name: 'Company10',
    symbol: 'C10',
    ratingID: '1',
    stockID: '2'
  },
]

const res = diffArr.filter(cv => !dbArr.find(e => e.name === cv.name && e.ratingID === cv.ratingID && e.stockID === cv.stockID));

console.log(res)

第二,您期望数组不仅包含其他元素(diffArr中的元素,但不包含dbArr),还包含移除的元素(dbArr中的元素,但不包含{{1 }})。要包括这些元素,您还必须迭代diffArr

dbArr

另一条注释,const dbArr = [{ name: 'Company1', symbol: 'C1', ratingID: '1', stockID: '2' }, { name: 'Company2', symbol: 'C2', ratingID: '1', stockID: '2' }, { name: 'Company3', symbol: 'C3', ratingID: '1', stockID: '2' }, { name: 'Company4', symbol: 'C4', ratingID: '1', stockID: '2' }, ]; const diffArr = [{ name: 'Company1', symbol: 'C1', ratingID: '1', stockID: '2' }, { name: 'Company6', symbol: 'C6', ratingID: '1', stockID: '2' }, { name: 'Company1', symbol: 'C1', ratingID: '5', stockID: '3' }, { name: 'Company10', symbol: 'C10', ratingID: '1', stockID: '2' }, ]; let same = (cv1, cv2) => cv1.name === cv2.name && cv1.ratingID === cv2.ratingID && cv1.stockID === cv2.stockID; let res1 = diffArr.filter(cv1 => !dbArr.find(cv2 => same(cv1, cv2))); let res2 = dbArr.filter(cv1 => !diffArr.find(cv2 => same(cv1, cv2))); let res = [...res1, ...res2]; console.log(res); 应该替换为find,因为它更清晰,更符合意图。 some说:“数组的任何元素是否通过谓词?”;而array.some(predicate)说:“哪个是通过谓词的第一个元素?” (mdn

答案 1 :(得分:1)

也许只是遍历两个数组,然后在结果中找不到元素时将其添加到结果中。

const dbArr = [{
    name: 'Company1',
    symbol: 'C1',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company2',
    symbol: 'C2',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company3',
    symbol: 'C3',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company4',
    symbol: 'C4',
    ratingID: '1',
    stockID: '2'
  },
]

const diffArr = [{
    name: 'Company1',
    symbol: 'C1',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company6',
    symbol: 'C6',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company1',
    symbol: 'C1',
    ratingID: '5',
    stockID: '3'
  },
  {
    name: 'Company10',
    symbol: 'C10',
    ratingID: '1',
    stockID: '2'
  },
]

const res = [];
dbArr.map(cv => {if(res.find(e => e.name === cv.name))return cv; res.push(cv)});
diffArr.map(cv => {if(res.find(e => e.name === cv.name))return cv; res.push(cv)});

答案 2 :(得分:1)

我将.reduceJSON.parse一起使用,其想法是它将检查字符串数组并将不存在的值压入累加器

const dbArr = [{
    name: 'Company1',
    symbol: 'C1',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company2',
    symbol: 'C2',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company3',
    symbol: 'C3',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company4',
    symbol: 'C4',
    ratingID: '1',
    stockID: '2'
  },
]

const diffArr = [{
    name: 'Company1',
    symbol: 'C1',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company6',
    symbol: 'C6',
    ratingID: '1',
    stockID: '2'
  },
  {
    name: 'Company1',
    symbol: 'C1',
    ratingID: '5',
    stockID: '3'
  },
  {
    name: 'Company10',
    symbol: 'C10',
    ratingID: '1',
    stockID: '2'
  },
];

const res = diffArr.reduce((acc, item, index, self) => {

  if (typeof acc !== 'object') {
    acc = [];
  }
  acc.push(JSON.stringify(item)); // push the item as a string

  dbArr.forEach(i => {
    let j = JSON.stringify(i); // make dbArr items strings
    if (acc.indexOf(j) === -1) { // check if the item exists in the accumulator
      acc.push(j); // add it
    }
  })

  if (index === self.length - 1) { // when we reach the last index, we'll convert the strings back to Objects
    acc = acc.map(i => JSON.parse(i));
  }

  return acc;

}, []);

console.log(res)