#javascript #arrays #json #loops
Вопрос:
У меня есть 2 массива объектов с именами ProductColor
Profile
, в этом оба массива имеют общее значение fieldname
, здесь я пытаюсь создать отдельный массив с несколькими элементами из обоих массивов , ниже приведен подробный массив и ожидаемый массив
массив1
var Profiles = [
{
fieldname: 'Black',
filename: 'Blackcolor1630667241215.JPEG',
},
{
fieldname: 'Black',
filename: 'Blackcolor1630667241217.JPEG',
},
{
fieldname: 'White',
filename: 'Whitecolor1630667241218.JPEG',
},
{
fieldname: 'White',
filename: 'Whitecolor1630667241219.JPEG',
}
]
массив2
var productimg = [{
keyId: 0,
objId: 0,
fieldname: 'Black'
},
{
keyId: 1,
objId: 0,
fieldname: 'Black'
},
{
keyId: 0,
objId: 1,
fieldname: 'White'
},
{
keyId: 1,
objId: 1,
fieldname: 'White'
}]
Пытался
const finalImgset = [];
Profiles.map((val) =>{
productimg.map((img) =>{
console.log(val.fieldname, img.fieldname);
if(val.fieldname == img.fieldname){
finalImgset.push({
src: val.filename,
objkey: img.objId,
keyId: img.keyId,
})
}
})
})
но это работает не так, как ожидалось, вот мой ожидаемый результат
var finalarray = [
{
filename: 'Blackcolor1630667241215.JPEG',
keyId: 0,
objId: 0,
fieldname: 'Black'
},
{
filename: 'Blackcolor1630667241217.JPEG',
keyId: 1,
objId: 0,
fieldname: 'Black'
},
{
filename: 'Whitecolor1630667241218.JPEG',
keyId: 0,
objId: 1,
fieldname: 'White'
},
{
filename: 'Whitecolor1630667241219.JPEG',
keyId: 1,
objId: 1,
fieldname: 'White'
}]
любая помощь — это предложения, которые действительно ценятся,
Комментарии:
1. Имена файлов не совпадают с вашими исходными данными и ожидаемым результатом. Это намеренно? Я неправильно понял? Последняя запись:
filename: 'Whitecolor1630667241219.JPEG'
становитсяfilename: 'Whitecolor1630667020772.JPEG'
2. привет @LaytonGB я обновил свой массив, пожалуйста, проверьте сейчас
3.
both arrays common value is fieldname
, ноfieldname
это не уникально, как вы объединяете элемент, если у них обоих одно и то жеfieldname
?
Ответ №1:
Вам нужно получить массив максимальной длины и выполнить цикл над ним, используя индекс для объединения двух объектов массива, вот так:
const array1 = [
{
fieldname: "Black",
filename: "Blackcolor1630667241215.JPEG"
},
{
fieldname: "Black",
filename: "Blackcolor1630667241217.JPEG"
},
{
fieldname: "White",
filename: "Whitecolor1630667241218.JPEG"
},
{
fieldname: "White",
filename: "Whitecolor1630667241219.JPEG"
}
];
const array2 = [
{
keyId: 0,
objId: 0,
fieldname: "Black"
},
{
keyId: 1,
objId: 0,
fieldname: "Black"
},
{
keyId: 0,
objId: 1,
fieldname: "White"
},
{
keyId: 1,
objId: 1,
fieldname: "White"
}
];
const maxLength = Math.max(array1.length, array2.length)
const finalArray = [];
for (let i = 0; i < maxLength; i ) {
finalArray.push({
...(array1[i] ?? {}),
...(array2[i] ?? {}),
})
}
console.log(finalArray);
Вот более общая функция слияния:
function mergeArrayOfObjects(...arrays) {
let maxLength = 0;
for (let i = 0, length = arrays.length; i < length; i ) {
maxLength = Math.max(maxLength, arrays[i].length);
}
const finalArray = [];
for (let i = 0; i < maxLength; i ) {
const mergedObject = {};
for (let j = 0, length = arrays.length; j < length; j ) {
Object.assign(mergedObject, arrays[j][i] ?? {});
}
finalArray.push(mergedObject);
}
return finalArray;
}
Передайте в него столько массивов mergeArrayOfObjects
, сколько потребуется:
console.log(mergeArrayOfObjects(array1, array2, array3));
Комментарии:
1. максимальная длина и петля for не требуются
2. Это если вы не хотите, чтобы ошибки времени выполнения индекса выходили за рамки. Это наиболее эффективный способ объединения двух объектов массива.
3. Как работает
...
и?? {}
? Не могли бы вы показать какое-нибудь объяснение?4.
...
скопирует исходный объект и создаст?? {}
array1[i]
пустой объект, если для него нет значенияarray1[i]
Ответ №2:
Важно различать соответствие на основе порядка и соответствие на основе свойств. Хотя ваши объекты имеют совпадающие fieldname
свойства, вы сопоставляете их по порядку, потому что существуют разные записи с одним и тем же fieldname
свойством.
Хотя большинство других ответов работают, я думаю, что это будет самым быстрым.
var Profiles = [{ fieldname: 'Black',filename: 'Blackcolor1630667241215.JPEG',},{fieldname: 'Black',filename: 'Blackcolor1630667241217.JPEG',},{fieldname: 'White',filename: 'Whitecolor1630667241218.JPEG',},{fieldname: 'White',filename: 'Whitecolor1630667241219.JPEG',}];
var productimg = [{keyId: 0,objId: 0,fieldname: 'Black'},{keyId: 1,objId: 0,fieldname: 'Black'},{keyId: 0,objId: 1,fieldname: 'White'},{keyId: 1,objId: 1,fieldname: 'White'}];
function mergeArrays(arr1, arr2) {
if (arr1.length !== arr2.length) return; // stop if different lengths
let newArr = [];
for (let i in arr1) // for each index
newArr.push({ ...arr1[i], ...arr2[i] }); // combine the properties of both arrays to make a new object and add it to `newArr`
return newArr;
}
console.log( mergeArrays( Profiles, productimg ) );
.as-console-wrapper{min-height:100%} /* format console output */
Ответ №3:
Просто сопоставьте Profiles
, объедините узлы в productimg
var Profiles = [
{
fieldname: 'Black',
filename: 'Blackcolor1630667241215.JPEG',
},
{
fieldname: 'Black',
filename: 'Blackcolor1630667241217.JPEG',
},
{
fieldname: 'White',
filename: 'Whitecolor1630667241218.JPEG',
},
{
fieldname: 'White',
filename: 'Whitecolor1630667241219.JPEG',
}
]
var productimg = [{
keyId: 0,
objId: 0,
fieldname: 'Black'
},
{
keyId: 1,
objId: 0,
fieldname: 'Black'
},
{
keyId: 0,
objId: 1,
fieldname: 'White'
},
{
keyId: 1,
objId: 1,
fieldname: 'White'
}]
const finalarray = Profiles.map((node, index) => {
return { ...node, ...productimg[index] };
});
console.log(finalarray)
Ответ №4:
Предполагая, что оба имеют одинаковую длину, и вы объединяете один и тот же объект индекса в обоих массивах. использование функции spread( ...
) для объединения двух объектов и map
создания нового объекта
var Profiles = [
{
fieldname: 'Black',
filename: 'Blackcolor1630667241215.JPEG',
},
{
fieldname: 'Black',
filename: 'Blackcolor1630667241217.JPEG',
},
{
fieldname: 'White',
filename: 'Whitecolor1630667241218.JPEG',
},
{
fieldname: 'White',
filename: 'Whitecolor1630667241219.JPEG',
}
]
var productimg = [{
keyId: 0,
objId: 0,
fieldname: 'Black'
},
{
keyId: 1,
objId: 0,
fieldname: 'Black'
},
{
keyId: 0,
objId: 1,
fieldname: 'White'
},
{
keyId: 1,
objId: 1,
fieldname: 'White'
}]
let result = Profiles.map((profile, index) => {
return {...profile, ...productimg[index] }
})
console.log(result)
Комментарии:
1. Это неверно, это будет работать только в том случае, если они отсортированы с одинаковыми именами полей…
2. привет, Вайра, спасибо тебе за ответы, но это не то, что я ищу. я хочу показать все 4 элемента объекта в конечном массиве
3. @CodeBug он напечатает все 4, если вы используете свой массив, я использую только более короткий массив длиной 2, чтобы ответ был небольшим
4. @Alexis он на самом деле не соответствует именам полей, так как в его примере они не уникальны в его примере
5. @vaira им не нужно быть уникальными, чтобы соответствовать… взгляните на мой ответ