将数组添加到数组的数组

Adding arrays to an array of arrays

我确信这非常简单,我真的不想要一个完整的解决方案,但在我学习的过程中指出了正确的方向。

我有:

let randomArray = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];

目标是让它看起来像这样,将类似的项目分组:

[[1,1,1,1],[2,2,2],[10],[20,20],[391],[392],[591]]

我下面的代码排列,分组都很好。我将温度推送到我的组阵列。但是当我重置我的“tempArray”以使其为下一个“组”做好准备时,它也会从我的组中删除数据。因为有关联?我假设?也许吧?

最后只剩下最后一项了。

如何阻止它这样做?

    // My SOlution
let randomArray = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];
let tempArray = [];
let groupArray = [];

function cleanTheRoom (arr) {
    let ascendingArray = arr.sort(function(a,b) {
        return a - b;
    });
    tempArray.push(randomArray[0])
    for (let i = 1; i <= randomArray.length; i++) {
        if (randomArray[i] === tempArray[0]) {
            tempArray.push(randomArray[i])
        } else {
            groupArray.push(tempArray);
            tempArray = []
            tempArray.push(randomArray[i])
        }
    } console.log(groupArray)
}

cleanTheRoom(randomArray);

我把你的代码改了一些。

  • Array#sort 就地排序。无需分配给新变量。

  • 从零迭代并直接查看数据,方法是使用索引减一和索引处的值。如果不相等,则找到一个新组。在这种情况下,只需将一个空数组分配给 groupArray 并将该组推送到结果。

    这种方法不是使用相同的对象引用,而是通过将零分配给 length 来清空数组,而是采用一个新数组。

  • 将值推到 if 语句之外,因为它在 thenelse[=43= 中翻了一番]部分。

  • 最后 return 数组与组。

function cleanTheRoom(array) {
    let result = [];
    let groupArray;

    array.sort(function(a, b) {
        return a - b;
    });

    for (let i = 0; i < array.length; i++) {
        if (array[i - 1] !== array[i]) {
            groupArray = [];
            result.push(groupArray);
        }
        groupArray.push(array[i]);
    }

    return result;
}

let randomArray = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];

console.log(cleanTheRoom(randomArray));

您的代码存在三个主要问题:

  1. 您正在函数内部使用 randomArray 但您应该使用 ascendingArray

  2. tempArray.length = 0 - 此语句改变了原始的 tempArray,并且由于您将 tempArray 数组推入 groupArray,更改为 tempArray 也反映在 groupArray 中。

    您可以克隆 tempArray 并将 tempArray 的副本推送到 groupArray

    groupArray.push([...tempArray]);
    

    或者您可以将新的空数组分配给 tempArray

    tempArray = [];
    
  3. 当它是循环的最后一次迭代时,您不会将 tempArray 的内容推送到 groupArray 中。这将导致 groupArray 不包含排序数组中的最后一个数字,即 591。您需要检查当前迭代是否是循环的最后一次迭代。如果是,请将 tempArray 推入 groupArray

    for (let i = 1; i < ascendingArray.length; i++) {
      ...
    
      if (i == ascendingArray.length - 1) {
        groupArray.push(tempArray);
      } 
    } 
    

这是您的代码的简化版本:

let randomArray = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];

function cleanTheRoom(arr) {
  let tempArray = [];
  let groupArray = [];

  let ascendingArray = arr.sort(function (a, b) {
    return a - b;
  });

  for (let i = 0; i < ascendingArray.length; i++) {
    tempArray.push(ascendingArray[i]);

    if (ascendingArray[i + 1] !== ascendingArray[i]) {
      groupArray.push(tempArray);
      tempArray = [];
    }
  }

  console.log(groupArray);
}

cleanTheRoom(randomArray);

可能还有更快的方法,但我快速尝试了一下:

  • 首先,我们将数组分解成组
  • 然后我们不对整个数组进行排序,而是仅对组的键进行排序,以避免对数组进行第二次完整迭代。

我对组使用了 Map 而不是字典,因为我们可以巧妙地利用 Map.set 函数。它 return 是我们需要的整个 Map 作为 reduce 中的 return 值。

const randomArray = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const isGroup = (acc, number) => Array.isArray(acc.get(number));
const setGroup = (acc, number) => acc.set(number, isGroup(acc, number) ? acc.get(number).concat([number]) : [number]);
const unorderedNumberGroups = randomArray.reduce(setGroup, new Map());
const order = [...unorderedNumberGroups.keys()].sort((a, b) => a - b);
const orderedNumberGroups = order.reduce((acc, key) => acc.concat([unorderedNumberGroups.get(key)]), []);
console.log(orderedNumberGroups);

这里是一个更易调试的版本,这样你就可以尝试理解上面的版本:

const randomArray = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const isGroup = (acc, number) => Array.isArray(acc.get(number));
const unorderedNumberGroups = randomArray.reduce((acc, number) => {
  if (isGroup(acc, number)) {
    const mapEntry = acc.get(number);
    const newEntry = mapEntry.concat([number]);
    return acc.set(number, newEntry); // we need to return the acc, the Map.set method returns the whole Map
  } else {
    return acc.set(number, [number]); // we need to return the acc, the Map.set method returns the whole Map
  }
}, new Map()); // initialize the accumulator we an empty Map
const keysAsArray = [...unorderedNumberGroups.keys()];
const order = keysAsArray.sort((a, b) => a - b);
const orderedNumberGroups = order.reduce((acc, key) => {
  const arrayForTheKey = unorderedNumberGroups.get(key);
  return acc.concat([arrayForTheKey]); // note the breakets!

  // equivalent code:
  // acc.push(arrayForTheKey);
  // return acc;
}, []); // initialize the accumulator with an empty Array
console.log(orderedNumberGroups);