非常简单。
我需要构造一个接受两个数组和一个回调的函数objOfMatches
。 objOfMatches将构建一个对象并返回它。为了构建对象,objOfMatches
将使用回调测试第一个数组的每个元素,以查看输出是否与第二个数组的相应元素(按索引)匹配。如果存在匹配项,则第一个数组中的元素将成为对象中的键,而第二个数组中的元素将成为对应的值。
function objOfMatches(array1, array2, callback) {
//create obj
var obj = {}
//loop thru first array
for(let i = 0; i < array1.length; i++) {
for (let j = 0; j < array2.length; j++) {
if (callback(array1[i]) === array2[j]) {
obj.array1[i] = array2[j];
}
}
}
return obj;
}
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));
// should log: { hi: 'HI', bye: 'BYE', later: 'LATER' }
看起来很简单,但是我还不完全理解为什么它会在控制台中引发TypeError。 (TypeError: Cannot set property '0' of undefined)
有人可以解释发生了什么事吗?
答案 0 :(得分:1)
如果要匹配对应的元素,则不需要遍历两个数组。您可以遍历一个对象,并使用索引在另一个对象中找到相应的对象。
reduce()
对此非常有用,因为它可以让您就地构建返回对象,并提供当前循环迭代的索引。您只需运行测试,然后在测试正确的情况下分配键/值即可。
function objOfMatches(arr1, arr2, callback){
return arr1.reduce((obj, current, index) => {
if(arr2[index] === callback(current)) obj[current] = arr2[index]
return obj
}, {})
}
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));
答案 1 :(得分:1)
假设两个数组的长度相等,并且匹配元素的索引匹配,那么非常简单的reduce可以使您到达那里:
const x = ['hi', 'howdy', 'bye', 'later', 'hello'],
y = ['HI', 'Howdy', 'BYE', 'LATER', 'hello'];
console.log(x.reduce((a,v,i)=>Object.assign(a,{[v]:y[i]}),{}))
如果您需要检查匹配项的存在和位置,则需要进行以下修改才能使Array.prototype.reduce
为您工作:
const x = ['hi', 'later', 'howdy', 'bye', 'hello', 'foo'],
y = ['HI', 'baz', 'Howdy', 'BYE', 'LATER', 'hello', 'bar'];
console.log(x.reduce((a,v)=> {
let i = y.indexOf(v.toUpperCase())
return i === -1 ? a : Object.assign(a, {[v]:y[i]})
},{}
))
答案 2 :(得分:0)
按照您的方法,您应该使用此obj[array1[j]] = array2[i]
,在此处为示例:
function objOfMatches(array1, array2, callback) {
//create obj
var obj = {}
//loop thru first array
for(let i = 0; i < array1.length; i++) {
for (let j = 0; j < array2.length; j++) {
if (callback(array1[i]) === array2[j]) {
if(!array1[j] in obj) obj[array1[j]] = []
obj[array1[j]] = array2[i];
}
}
}
return obj;
}
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) { return str.toUpperCase(); }));