#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']