Как создать объект из совпадений нескольких массивов - PullRequest
0 голосов
/ 15 декабря 2018

Учитывая array1 и array2 Я должен создать объект, свойства и значения которого получаются из совпадений пересечений между двумя массивами.

function objOfMatches(array1, array2, cb) {

    var obj = {};   
    var newArray1 = array1.map(cb);

    for (let i = 0; i < newArray1.length; i++) {
        if( !(array2.indexOf(newArray1[i]) == -1) ) {           
            obj[newArray1[i].toLowerCase()] = newArray1[i];
        }
    }

    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' }

Есть ли лучший или более чистый способ записиэто чем эта реализация?

Ответы [ 5 ]

0 голосов
/ 15 декабря 2018

Вы можете попробовать это

function objOfMatches(array1, array2, cb) {
    return array1.reduce((op,cur,i)=>{
      if(array2.includes(cur.toUpperCase())){
        op[cur] = array2[i];
      }
      return op;
    },{})
}
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello']));
// should log: { hi: 'HI', bye: 'BYE', later: 'LATER' }
0 голосов
/ 15 декабря 2018

Вы можете использовать предстоящий fromEntries. Огромное предостережение - текущая совместимость с браузером - только Firefox atm в соответствии с MDN .

Но: просто сопоставьте два массива, чтобы объединить их, затем fromEntries на этомобъединенный массив, чтобы дать вам объект.

function objOfMatches(arr1, arr2) {
  const merged = arr1.map((el, i) => [el, arr2[i]]);
  return Object.fromEntries(merged);
}

const result = objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello']);
console.log(result);
0 голосов
/ 15 декабря 2018

Вы можете взять Set и отобразить общие части для нового объекта.

Этот подход использует два цикла, по одному для каждого массива.

function objOfMatches(array1, array2) {
    var s = new Set(array1);

    return Object.assign(...array2.map(v => s.has(v) && { [v.toLowerCase()]: v }));
}
console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'].map(s => s.toUpperCase()), ['HI', 'Howdy', 'BYE', 'LATER', 'hello']));
0 голосов
/ 15 декабря 2018

Вы можете использовать reduce() для создания объекта, только добавляя ключ, в котором найдено совпадение.

function objOfMatches(array1, array2, cb) {
  return array1.reduce((obj, item) => {
    if (array2.includes(cb(item))) obj[item] = cb(item)
    return obj
  }, {})

}


console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) {
  return str.toUpperCase();
}));

Это просто, но будет иметь поведение O (n²), потому что includes просматривает array2 для каждого элемента в array1.Это может не иметь значения для небольших списков, но если списки велики, возможно, стоит создать какой-то хеш (например, Set или объект), чтобы дать вам постоянный поиск в array2.

Что-то вроде:

function objOfMatches(array1, array2, cb) {
  let set = new Set(array2)
  return array1.reduce((obj, item) => {
    if (set.has(cb(item))) obj[item] = cb(item)
    return obj
  }, {})

}


console.log(objOfMatches(['hi', 'howdy', 'bye', 'later', 'hello'], ['HI', 'Howdy', 'BYE', 'LATER', 'hello'], function(str) {
  return str.toUpperCase();
}));
0 голосов
/ 15 декабря 2018

Совершенно неясно, что должна делать функция, что затрудняет ее чтение.Вместо этого вы должны разделить задачи:

  const intersection = (a, b) => a.filter(it => b.includes(it));
  const toMap = (values, mapper) => Object.assign({}, ...values.map(value => ({ [mapper(value)]: value })));

  const matches = intersection(array1.map(it => it.toUpperCase()), array2);
  const result = toMap(matches, value => value.toLowerCase());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...