Построение объекта путем циклического перебора двух массивов - PullRequest
0 голосов
/ 13 сентября 2018

Довольно просто.

Мне нужно создать функцию 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)

Может кто-нибудь объяснить, что происходит?

Ответы [ 3 ]

0 голосов
/ 13 сентября 2018

Если вы хотите сопоставить с соответствующими элементами, вам не нужно циклически проходить через оба массива. Вы можете перебрать один и использовать индекс, чтобы найти соответствующий объект в другом.

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(); }));
0 голосов
/ 14 сентября 2018

Если предположить, что оба массива имеют одинаковую длину, а индексы совпадающих элементов совпадают, очень прямое сокращение приведет вас туда:

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]})
  },{}
))
0 голосов
/ 13 сентября 2018

Следуя вашему подходу, вы должны использовать это 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(); }));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...