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

javascriptweb developmentfront end technologyobject oriented programming

问题陈述要求用户在 JavaScript 中将一个数组中的所有记录添加到另一个数组中的每个记录中,刚刚读取的语句似乎很难理解和实现代码。最简单的意思是,给定两个包含不同值集合的数组,我们需要生成一个组合的新对象数组,这样新生成的数组就是两个数组中所有可能值的集合,比如数组 1 和数组 2。

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

JavaScript 中的笛卡尔积是什么?

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

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

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

给定两个数组:

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 循环的每次迭代生成每对可能的回调 foreach,从而生成数组元素的可能组合。

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

步骤 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) 的二次最差时间复杂度,但请记住两个数组的长度不同,因此数组 1 的长度为 m,数组 2 的长度为 n,并且可能存在 m>n 或 m<n 或 m=n 。因此,时间复杂度为 O(mn),取决于数组 1 和数组 2 的长度。由于没有额外分配内存,因此空间复杂度为 O(1)。

算法 - 使用 Map 和 Reduce 方法

步骤 1:声明一个名为 CombineArrayOfRecords 的函数,该函数以用户提供的数组 1 和数组 2 作为输入源。

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

步骤 3:如果没有提供初始值,则参数中的累加器取数组 1 的第一个值,当前值取第二个值,以便在其中将 map 函数应用于数组 2,用于将数组 2 的每个元素映射到数组 1 的每个成员上,该函数调用以用户和键值对形式成型的 Reducer 函数城市。

步骤 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 方法,这是最有效的用例。


相关文章