выполните цикл над 2 массивами и создайте один массив, как ожидалось

#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 им не нужно быть уникальными, чтобы соответствовать… взгляните на мой ответ