【问题标题】:loop over 2 arrays and make a single array as expected循环2个数组并按预期制作一个数组
【发布时间】:2021-11-01 18:34:44
【问题描述】:

我有 2 个对象数组,分别命名为 ProductColorProfile,这两个数组的共同值是 fieldname,这里我想要完成的是创建一个单独的数组,其中包含很少的元素数组,下面是详细数组和预期数组

array1

var Profiles = [
{ 
 fieldname: 'Black',
 filename: 'Blackcolor1630667241215.JPEG',
},
{
  fieldname: 'Black',
  filename: 'Blackcolor1630667241217.JPEG',
},
{
  fieldname: 'White',
  filename: 'Whitecolor1630667241218.JPEG',
},
{
  fieldname: 'White',
  filename: 'Whitecolor1630667241219.JPEG',
 }
]

array2

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

任何帮助都是非常感谢的建议,

【问题讨论】:

  • 原始数据中的文件名与预期输出不匹配。这是故意的吗?我是不是误会了?最后一个条目:filename: 'Whitecolor1630667241219.JPEG' 变为 filename: 'Whitecolor1630667020772.JPEG'
  • 嗨@LaytonGB 我更新了我的阵列,请立即查看
  • both arrays common value is fieldname,但是fieldname不是唯一的,如果它们都具有相同的fieldname,你如何合并项目?

标签: javascript arrays json loops


【解决方案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));

【讨论】:

  • 最大长度和for循环不是必需的
  • 如果您不希望索引越界运行时错误。这是合并两个数组对象的最高效方式。
  • ...?? {} 是如何工作的?你能解释一下吗?
  • ... 将复制原始对象,如果array1[i] 没有值,?? {} 将使array1[i] 成为空对象
【解决方案2】:

假设两者的长度相同,并且您在两个数组中组合相同的索引对象。 使用 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)

【讨论】:

  • 这是不正确的,只有在它们使用相同的字段名排序时才有效...
  • 嗨 vaira,谢谢你的回答,但这不是我要找的。我想在最终数组中显示所有 4 个对象元素
  • @CodeBug 如果你使用你的数组,它将打印所有 4 个,我只使用长度为 2 的较短数组来保持答案小
  • @Alexis 他实际上与 fieldNames 不匹配,因为在他的示例中它们不是唯一的
  • @vaira 他们不需要是唯一的来匹配...看看我的答案
【解决方案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】:

    区分基于order的匹配和基于properties的匹配很重要。尽管您的对象具有匹配的 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 */

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 2011-08-28
      相关资源
      最近更新 更多