JS 函数 - 比较 2 个对象数组(每个数组中都有数组对象)
Posted
技术标签:
【中文标题】JS 函数 - 比较 2 个对象数组(每个数组中都有数组对象)【英文标题】:JS function - to compare 2 arrays of objects (with array object in each of the array) 【发布时间】:2018-07-29 21:54:57 【问题描述】:我有一个用户列表以及他们已经收到的内容。
users = [
name: 'Steve', received_contents: ['1a', '1b', '3c'] ,
name: 'Virginie', received_contents: ['3a', '2b', '3c'] ,
name: 'Fiona', received_contents: ['1b', '2a', '3b'] ,
name: 'Jenny', received_contents: ['3b', '2c', '1b'] ,
name: 'James', received_contents: ['2b', '1b', '3a'] ,
name: 'Fede', received_contents: ['2c', '3a', '1c'] ,
name: 'Sara', received_contents: ['3a', '2c', '3b'] ,
name: 'Tizi', received_contents: ['2b', '1b', '2a'] ,
name: 'Thomas', received_contents: ['3c', '2b', '1a'] ,
]
// 这些是下一批货的箱子和里面的东西
boxes = [
code: 'gr1', contents: ['1a', '1b'] ,
code: 'gr2', contents: ['1a', '2b'] ,
code: 'gr3', contents: ['1b', '2c'] ,
code: 'gr4', contents: ['2c', '3c'] ,
code: 'gr5', contents: ['3b', '1c'] ,
]
任务是创建一个函数,该函数接受用户列表并返回用户列表和他们可以接收的框,而无需再次获取相同的内容。
对于如何使我的解决方案更有效、更省时,我有点困惑。
这是我的解决方案:
for (var i in users )
let user = users[i];
console.log("User "+user.name+ " can receive " + getReceivableBoxes(user.received_contents));
function getReceivableBoxes (contents)
let receivableBoxes = [];
for(var i in boxes)
let box = boxes[i];
let canReceive = canReceiveBox(contents, box);
if(canReceive)
receivableBoxes.push(box.code);
return receivableBoxes;
function canReceiveBox(received_contents, box)
let receivableBoxes = [];
for (var i = 0; i < received_contents.length; i++)
for (var j = 0; j < box.contents.length; j++)
if (box.contents[j] === received_contents[i])
return false;
return true;
【问题讨论】:
How to get the difference between two arrays of objects in javascript的可能重复 @GeorgeJempty 该问题具有不同类型的数组。我将我的解决方案提供给其他人检查。 【参考方案1】:性能
JS
function getReceivableBoxes(user)
const receivableBoxes = [];
for(let b in boxes)
const box = boxes[b];
const contents = box.contents;
const filtered = [];
for(var i = 0, k = contents.length; i < k; i++)
if(user.received_contents.indexOf(contents[i]) > -1)
break;
filtered.push(contents[i]);
if(filtered.length === contents.length)
receivableBoxes.push(box.code);
return receivableBoxes;
精简版
JS
users.forEach(function(user)
var receivableBoxes = [];
boxes.forEach(function(box)
var contents = box.contents.filter(function(item)
return !user.received_contents.includes(item);
);
if(contents.length === box.contents.length)
receivableBoxes.push(box.code);
);
console.log('@@@ User ' + user.name + ' can receive ' + receivableBoxes.join(','));
);
ES6
const users = [
name: 'Steve', received_contents: ['1a', '1b', '3c'] ,
name: 'Virginie', received_contents: ['3a', '2b', '3c'] ,
name: 'Fiona', received_contents: ['1b', '2a', '3b'] ,
name: 'Jenny', received_contents: ['3b', '2c', '1b'] ,
name: 'James', received_contents: ['2b', '1b', '3a'] ,
name: 'Fede', received_contents: ['2c', '3a', '1c'] ,
name: 'Sara', received_contents: ['3a', '2c', '3b'] ,
name: 'Tizi', received_contents: ['2b', '1b', '2a'] ,
name: 'Thomas', received_contents: ['3c', '2b', '1a']
]
const boxes = [
code: 'gr1', contents: ['1a', '1b'] ,
code: 'gr2', contents: ['1a', '2b'] ,
code: 'gr3', contents: ['1b', '2c'] ,
code: 'gr4', contents: ['2c', '3c'] ,
code: 'gr5', contents: ['3b', '1c']
];
users.forEach((user) =>
const receivableBoxes = [];
boxes.forEach((box) =>
const contents = box.contents.filter((item) => !user.received_contents.includes(item));
if(contents.length === box.contents.length)
receivableBoxes.push(box.code);
);
console.log(`@@@ User $user.name can receive $receivableBoxes.join(',')`);
);
DEMO
【讨论】:
你确定第一个block会比es6方式执行得快吗? 是的。 for 循环将比 forEach 执行得更快,因为它不执行回调并且 indexOf 比 include 更快。【参考方案2】:你可以使用 ES6 数组函数、map、filter、find 等等。这些功能由现代 JavaScript 引擎的开发人员进行了高度优化。计时它通常在 0 或 1 毫秒内执行,与上面的代码运行的时间相同。
我还想指出,如果您在现代 JavaScript 面试的技术测试中使用 for 循环或 forEach,那么您的面试就会失败。
const users = [
name: 'Steve', received_contents: ['1a', '1b', '3c'] ,
name: 'Virginie', received_contents: ['3a', '2b', '3c'] ,
name: 'Fiona', received_contents: ['1b', '2a', '3b'] ,
name: 'Jenny', received_contents: ['3b', '2c', '1b'] ,
name: 'James', received_contents: ['2b', '1b', '3a'] ,
name: 'Fede', received_contents: ['2c', '3a', '1c'] ,
name: 'Sara', received_contents: ['3a', '2c', '3b'] ,
name: 'Tizi', received_contents: ['2b', '1b', '2a'] ,
name: 'Thomas', received_contents: ['3c', '2b', '1a'] ,
];
// These are the boxes for the next shipment and their contents
const boxes = [
code: 'gr1', contents: ['1a', '1b'] ,
code: 'gr2', contents: ['1a', '2b'] ,
code: 'gr3', contents: ['1b', '2c'] ,
code: 'gr4', contents: ['2c', '3c'] ,
code: 'gr5', contents: ['3b', '1c'] ,
];
const start = new Date();
const usersWithBoxes = users.map(user => (
user: user,
boxes: boxes.filter(box => box.contents.every(bc => !user.received_contents.find(rc => bc === rc)))
));
const end = new Date();
console.log(`Function took $end.getTime() - start.getTime()ms to run`);
console.log(usersWithBoxes.map(u => `$u.user.name can recieve boxes $u.boxes.map(b => b.code)`).join('\n'));
【讨论】:
以上是关于JS 函数 - 比较 2 个对象数组(每个数组中都有数组对象)的主要内容,如果未能解决你的问题,请参考以下文章