在 JavaScript 中将一个数组中的所有记录添加到另一个数组的每个记录中


问题陈述要求用户在 JavaScript 中将一个数组中的所有记录添加到另一个数组的每个记录中,仅阅读该语句似乎很难理解并在其上实现代码。最简单的含义是给定两个包含不同值集合的数组,我们需要生成一个组合的新数组对象,以便新生成的数组是两个数组中所有可能值的集合,例如数组 1 和数组 2。

问题陈述也可以用另一种方式实现,即查找用户给定的两个数组的笛卡尔积。

什么是 JavaScript 中的笛卡尔积?

笛卡尔积实际上是数学集合论中的一个概念,给定两个集合 A 和 B,A * B 是集合的所有可能组合,其中它的值存在于 A 或 B 中,这里问题陈述用用户给定的输入数组替换了状态。

在 JavaScript 中,代码逻辑将笛卡尔积视为一个问题陈述,其解决方案的基本支柱是遍历两个数组的每个元素,然后将第一个数组的每个元素与第二个数组的每个元素配对。

关于问题陈述的解决方案的视觉效果如下所示

给定两个数组

const array1 = [ 1, 2 , 3 ];
const array2 = [ 'x' ,'y' , 'z' ] ;

const caretsianProductofArrays = [ [1,'x'] , [1,'y''] , [1,'z'] , [2,'x'] , 
[2,'y'] , [2,'z'] , [3,'x'] , [3,'y'] , [3,'z'] ];

算法 - 使用循环

该算法遵循从给定的两个数组输入中形成每个有序对的核心逻辑。

步骤 1:声明一个名为 combineTwoArrayRecords 的函数,该函数将 array1 和 array2 作为输入。

步骤 2:声明并初始化名为 resultArr 的结果数组为空数组。

步骤 3:我们使用 foreach 循环遍历数组中的元素,该数组使用 foreach 循环作为回调函数来生成每次外部 foreach 循环迭代的所有可能的对,从而生成数组元素的所有可能组合。

步骤 4:为了将数组的数组转换为对象的数组,我们在每次迭代的 push 方法中传递了键和值参数,以使其将两个数组的每个元素的所有可能组合塑造成键值对和数组对象的格式。

步骤 5:一旦所有数组的长度都耗尽到 javascript 的 length 属性,我们就返回包含两个数组中所有可能元素组合的结果对象,以键值对的形式。

示例

function combineTwoArrayRecords(arr1 , arr2)
{
   let resultArr =[];
   arr1.forEach(itemArr1 => {
     arr2.forEach(itemArr2 =>{
       resultArr.push({
         'User' : itemArr1 ,
         'City' : itemArr2
       })
     })
   })
   return resultArr;
}

const nameArray = [ "Michael" , "James" ,"Steve"];
const cityArray = [ "NewYork" , "Japan" , "USA" ,"China"]

const finalCombinations = combineTwoArrayRecords( nameArray , cityArray);

console.log(finalCombinations);

输出

[
  { User: 'Michael', City: 'NewYork' },
  { User: 'Michael', City: 'Japan' },
  { User: 'Michael', City: 'USA' },
  { User: 'Michael', City: 'China' },
  { User: 'James', City: 'NewYork' },
  { User: 'James', City: 'Japan' },
  { User: 'James', City: 'USA' },
  { User: 'James', City: 'China' },
  { User: 'Steve', City: 'NewYork' },
  { User: 'Steve', City: 'Japan' },
  { User: 'Steve', City: 'USA' },
  { User: 'Steve', City: 'China' }
]

这是在 javascript 中使用嵌套循环将一个数组中的所有记录添加到另一个数组中每个记录的最简单方法之一,但此类算法的时间复杂度会受到很大影响。

时间和空间复杂度

由于算法中存在两个循环,因此我们遇到了 O(n^2) 的二次最坏时间复杂度,但请记住,两个数组的长度并不相同,例如 array1 的长度为 m,array2 的长度为 n,并且可能 m>n 或 m

算法 - 使用 Map 和 Reduce 方法

步骤 1:声明一个名为 combineArrayOfRecords 的函数,该函数将 array1 和 array2 作为用户给定的输入源。

步骤 2:返回应用于 array1 的 reducer 函数,以便 reducer 函数使用累加器和当前值作为参数,reducer 函数实际上在调用数组的每个成员上执行,从而产生单个输出值,即我们解决问题陈述所需的单个可能组合。

步骤 3:如果未提供初始值,则参数中的累加器将获取 array1 的第一个值,而当前值将获取第二个值,以便在其中应用于 array2 的 map 函数用于将 array2 的每个元素映射到 array1 的每个成员上,该成员调用了 reducer 函数,并以 Users 和 City 的键值对形式进行塑形。

步骤 4:这就是累加器如何使用展开运算符存储使用 reduce 和 map 函数生成的每个元素的所有可能组合,并生成每个数组的不同记录,从而解决了问题陈述。

主代码 - 使用 Map 和 Reduce 方法

示例

function combineArrayOfRecords(arr1,arr2)
{
   return arr1.reduce((accumulator , currentValue)=>
     
     [...accumulator , ...arr2.map(currentItem=>(
       
         {
            'User' : currentValue ,
            'City' : currentItem
         }
     ))]
   
     
   , [])
}

const nameArray = [ "Michael" , "James" ,"Steve"]
const cityArray = [ "NewYork" , "Japan" , "USA" ,"China"]
const finalArray = combineArrayOfRecords(nameArray , cityArray);
console.log(finalArray);

输出

[
  { User: 'Michael', City: 'NewYork' },
  { User: 'Michael', City: 'Japan' },
  { User: 'Michael', City: 'USA' },
  { User: 'Michael', City: 'China' },
  { User: 'James', City: 'NewYork' },
  { User: 'James', City: 'Japan' },
  { User: 'James', City: 'USA' },
  { User: 'James', City: 'China' },
  { User: 'Steve', City: 'NewYork' },
  { User: 'Steve', City: 'Japan' },
  { User: 'Steve', City: 'USA' },
  { User: 'Steve', City: 'China' }
]

时间和空间复杂度

reduce 函数的最小时间复杂度为 O(n),因为 array1 在最坏情况下正在迭代数组的长度进行调用。即使在对 array1 的每个元素成员的每次调用中,map 也在数组上调用,遍历数组并花费 O(n) 时间复杂度,总计为 O(n) + O(n) = O(n) 时间复杂度。空间复杂度为 O(1),因为没有额外的内存分配。

结论

这就是我们如何通过逻辑思考和编码上下文来解决上述问题陈述,从嵌套 foreach 循环到 javascript 中 reduce 和 map 方法的最有效用例。

更新于:2023 年 8 月 22 日

375 次查看

开启你的 职业生涯

通过完成课程获得认证

开始
广告