Как преобразовать инициалы в одном массиве, чтобы они соответствовали значению во втором массиве

#javascript #arrays

#javascript #массивы

Вопрос:

У меня есть два массива:

 array1 = ['bob', 's', 'paul'];
array2 = ['bob', 'sue', 'paul'];
  

где я хочу преобразовать инициал в array1: ‘s’ в соответствующее имя в array2: ‘sue’.

Я также хочу, чтобы это работало в обратном порядке, где:

 array1 = ['bob', 'sue', 'paul'];
array2 = ['bob', 's', 'paul'];
  

чтобы ‘sue’ в array1 преобразовывался в ‘s’, соответствующий array2.

пока у меня есть эта функция:

 function findName(arr1, arr2) {
        for (let initial of arr1) {
            if (initial.length === 1) {
                return arr2.findIndex(name => name[0] === initial) != -1
            }
        }
    }
  

который вернет true, если инициал найдет подходящее имя, но мне нужна функция для фактического создания array3 таким образом, чтобы она преобразовывала инициал.

Другими словами:

 array1 = ['bob', 's', 'paul'];
array2 = ['bob', 'sue', 'paul'];
// array3 = ['bob', 'sue', 'paul']; //array 3 maintains the same sequence order as array 1

array1 = ['b', 'sue', 'paul'];
array2 = ['s', 'paul', 'bob'];
// array3 = ['bob', 's', 'paul']; //array 3 maintains the same sequence order as array 1

array1 = ['b', 'sue', 'paul', 'robert'];
array2 = ['s', 'paul', 'bob'];
// array3 = ['bob', 's', 'paul', 'robert']; //array 3 maintains the same sequence order as array 1

array1 = ['b', 'sue', 'paul'];
array2 = ['s', 'paul', 'bob', 'robert'];
// array3 = ['bob', 's', 'paul']; //array 3 maintains the same sequence order as array 1
  

В случаях, когда существует более одного одинакового инициала, просто преобразуйте первый инициал и сохраните второй:

 array1 = ['b', 'b', 'sue', 'paul'];
array2 = ['s', 'paul', 'bob', 'robert'];
// array3 = ['bob', 'b', 's', 'paul']; //array 3 maintains the same sequence order as array 1
  

если инициалы не найдут соответствующий набор, преобразуйте их последовательно:

 array1 = ['b', 'b', 'sue', 'paul'];
array2 = ['s', 'paul', 'bob', 'robert', 'bill'];
// array3 = ['bob', 'bill', 's', 'paul']; //array 3 maintains the same sequence order as array 1
  

Мне нужно иметь возможность использовать array3 вне этой функции.

Комментарии:

1. Использовать return arr1.map(…) ?

Ответ №1:

Преобразовать инициалы в одном массиве, чтобы они соответствовали значению во втором массиве

 let array1 = ['b', 'b', 'sue', 'paul'];
let array2 = ['s', 'paul', 'bob', 'robert', 'bill'];
let array3 = [];
array1.forEach(function(element) {
  let item =array2.find((el) => el.startsWith(element[0]));
  array3.push(item);
  var index = array2.indexOf(item);
  if (index > -1) {
    array2.splice(index, 1);
  }
});
 console.log(array3);  

Комментарии:

1. Вероятно, вам следует избегать повторяющегося array2.find((el) => el.startsWith(element[0])) вызова

Ответ №2:

Вы уже используете findIndex , чтобы определить, где в массиве находится элемент; поэтому вместо того, чтобы выбрасывать это и возвращать только логическое значение, чтобы определить, было ли оно -1 или нет, используйте его для индексации массива (если, конечно, оно не равно -1).

 i = arr2.findIndex(...);
result = (i > -1)? arr2[i] : initial;
  

Ответ №3:

Вы можете использовать map и найти

Идея заключается в —

  • Сначала мы перебираем A параметр.
  • Для каждого значения A мы сопоставляем его с инициалами в параметре B . alreadyUsed — это объект для отслеживания ранее использованных подстановок.
  • Если мы найдем значение, которое не является ложным, а также не использовалось ни для одной из предыдущих подстановок.затем мы сопоставляем это с конечным результатом. если нет, то мы сохраняем значение без изменений

 let switcher = (A,B)=>{
  let alreadyUsed = {}
  return A.map(e => {
    let value = B.find(b => b.startsWith( e[0] ) amp;amp; !alreadyUsed[b] ) || e
    if(value amp;amp; !alreadyUsed[value] ){
      alreadyUsed[value] = true
    }
    return value
  })
}


let array1 = ['bob', 's', 'paul'];
let array2 = ['bob', 'sue', 'paul'];

console.log(switcher(array1,array2))

let a1 = ['b', 'b', 'sue', 'paul'];
let a2 = ['s', 'paul', 'bob', 'robert', 'bill'];
console.log(switcher(a1,a2))  

Ответ №4:

Вы могли бы map использовать первый массив findIndex и splice вот так:

 function getArray3(array1, array2) {
  let array3 = array1.map(a => {
      let found;
      if (a.length === 1) {
        found = array2.findIndex(b => b.startsWith(a))
      } else {
        found = array2.findIndex(b => b.length === 1 amp;amp; a.startsWith(b))
      }

      return found === -1 ? a : array2.splice(found, 1)[0]
    })

  return array3
}

console.log(getArray3(['bob', 's', 'paul'], ['bob', 'sue', 'paul']))
// ['bob', 'sue', 'paul']; 

console.log(getArray3(['b', 'sue', 'paul'], ['s', 'paul', 'bob']))
// ['bob', 's', 'paul']; //array 3 maintains the same sequence order as array 1

console.log(getArray3(['b', 'sue', 'paul', 'robert'], ['s', 'paul', 'bob']))
// ['bob', 's', 'paul', 'robert']

console.log(getArray3(['b', 'b', 'sue', 'paul'], ['s', 'paul', 'bob', 'robert']))
// ['bob', 'b', 's', 'paul']

console.log(getArray3(['b', 'b', 'sue', 'paul'], ['s', 'paul', 'bob', 'robert', 'bill']))
// ['bob', 'bill', 's', 'paul']  

Вы могли бы использовать клон array2 using [...array2] , если вы не хотите мутировать array2

Ответ №5:

Вот решение, объединяющее map и findIndex :

 const mapInitials = (a1, a2) => {
  a2 = [...a2]; // clone because we're going to be modifying this one
  return a1.map((s1) => {
    const i = a2.findIndex(s2 => s2[0] === s1[0]);
    return i < 0 ? s1 : a2.splice(i, 1)[0];
  })
};

const test = (a1, a2) => console.log(...mapInitials(a1, a2));

test(['bob', 's', 'paul'],
     ['bob', 'sue', 'paul']);
  // ['bob', 'sue', 'paul']

test(['b', 'sue', 'paul'],
     ['s', 'paul', 'bob']);
  // ['bob', 's', 'paul']

test(['b', 'sue', 'paul', 'robert'],
     ['s', 'paul', 'bob']);
  // ['bob', 's', 'paul', 'robert']

test(['b', 'sue', 'paul'],
     ['s', 'paul', 'bob', 'robert']);
  // ['bob', 's', 'paul']

test(['b', 'b', 'sue', 'paul'],
     ['s', 'paul', 'bob', 'robert']);
  // ['bob', 'b', 's', 'paul']

test(['b', 'b', 'sue', 'paul'],
     ['s', 'paul', 'bob', 'robert', 'bill']);
  // ['bob', 'bill', 's', 'paul']