比较2个对象数组中的值并创建新数组js

时间:2018-08-07 12:11:38

标签: javascript reactjs

我有2个数组:

blockedNumbers: ['123', '456', '789', '247'];
contacts: [
           {name: 'Foo', numbers: [{ home:'123' }, { mobile:'456' }]}, 
           {name: 'Bar', numbers: [{ home:'789' }]}
          ]

我想创建一个新的阻止联系人数组,其中将包含:

[
  { name: Foo, numbers: [{ home:'123' }, { mobile:'456' }] }, 
  {name: 'Bar', numbers: [{ home:'789' }]} 
  '247'
]

因此,我尝试的解决方案首先循环访问被阻止的号码,然后对于每次联系,如果被阻止的号码为数字,则推送到数组。但结果显示为

[
  '123'
  { name: Foo, numbers: ['123', '456'] }, 
  {name: 'Bar', numbers: ['789']} 
  '456'
  '789'
  '247'
]

下面的代码:

const newBlacklistWithContacts = [];
blockedNumbers.forEach((blockedNumber) => {
    contacts.map((contact) => {
    // if blocked number in contacts
    Object.keys(contact.numbers).forEach((e) => {
    if (contact.numbers[e] === blockedNumber) {
        const alreadyAdded = newBlacklistWithContacts.find(blacklistContact => blacklistContact.name === contact.name);
        if (!alreadyAdded) {
            return newBlacklistWithContacts.push({ name: contact.name, numbers: contact.numbers });
        }
    }
    else if (!newBlacklistWithContacts.includes(blockedNumber)) {
        return newBlacklistWithContacts.push(blockedNumber);
    }
    });
    });
});

我敢肯定,有一种更有效的方法可以执行此操作,并且可以真正返回我需要的内容? (所有列入黑名单的联系人,如果不在联系人中,则只有数字)我在此项目中使用js和React.js

2 个答案:

答案 0 :(得分:4)

如果数据集确实很大,则可以通过在Set中进行 O(1)查找而不是使用indexOf或{{1}来优化算法}进行 O(n)查找:

includes
// Input
const blockedNumbers =  ['123', '456', '789', '247'];
const contacts = [{name: 'Foo', numbers: [{ home:'123' }, { mobile:'456' }]}, {name: 'Bar', numbers: [{ home:'789' }]}];

// Algorithm
const set = new Set(blockedNumbers);
const notused = new Set(blockedNumbers);
const newBlacklistWithContacts = contacts.filter(contact => 
    contact.numbers.map(obj => Object.values(obj)[0])
                   .filter(number => set.has(number) && (notused.delete(number) || true)).length
).concat(...notused);

// Output
console.log(newBlacklistWithContacts);

答案 1 :(得分:0)

var blockedNumbers = ['123', '456', '789', '247'];
var contacts = [{
        name: 'Foo',
        numbers: [{
            home: '123'
        }, {
            mobile: '456'
        }]
    },
    {
        name: 'Bar',
        numbers: [{
            home: '789'
        }]
    }
]

var blocks = [];
contacts.forEach(v1 => (v1.numbers.forEach(v2 => {
    blocks.push(Object.values(v2)[0]);
})));
blockedNumbers.forEach(val => (blocks.indexOf(val) == -1 ? contacts.push(val) : null));

console.log(contacts);