简体   繁体   English

将数组添加到数组数组

[英]Adding arrays to an array of arrays

I'm sure this is super simple, and I don't really want a complete solution, but pointing in the right direction as I'm learning.我确信这非常简单,我真的不想要一个完整的解决方案,但在我学习的过程中指向正确的方向。

I have:我有:

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

and the goal is to make it look like this, grouping like items:目标是让它看起来像这样,像项目一样分组:

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

My following code arranges, and groups fine.我的以下代码安排好,分组很好。 I push the temp to my Group array.我将 temp 推送到我的 Group 阵列。 But when I reset my "tempArray" to make it empty ready for the next "group", it removes the data from my group as well.但是当我重置我的“tempArray”以使其为下一个“组”准备好时,它也会从我的组中删除数据。 Because it's linked?因为有关联? I assume?我假设? Maybe?也许?

The only thing left at the end is the last item.最后只剩下最后一项了。

How do I stop it doing this?我如何阻止它这样做?

    // 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);

I took your code and changed some parts.我拿了你的代码并更改了一些部分。

  • Array#sort sorts in place. Array#sort就地Array#sort No need to assign to a new variable.无需分配给新变量。

  • Iterate from zero and have a look to the data directly, by using the value at index minus one and at the index.通过使用索引减一和索引处的值,从零开始迭代并直接查看数据。 If unequal, a new group is found.如果不相等,则找到一个新组。 In this case just assign an empty array to groupArray and push the group to the result.在这种情况下,只需将一个空数组分配给groupArray并将该组推送到结果。

    Instead of using the same object reference and just empty the array by assigning zero to length , this approach takes a new array.这种方法不是使用相同的对象引用,而是通过将零分配给length来清空数组,而是采用一个新数组。

  • Push the value outside of the if statement, because it was doubled in then and else part.将值推到if语句之外,因为它在thenelse部分被加倍。

  • Finally return the array with the groups.最后返回带有组的数组。

 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));

There are three main problems in your code:您的代码中存在三个主要问题:

  1. You are using randomArray inside the function but you should be using ascendingArray您在函数内部使用randomArray但您应该使用ascendingArray

  2. tempArray.length = 0 - this statement mutates the original tempArray and since you are pushing the tempArray array in the groupArray , changes to tempArray are reflected in the groupArray as well. tempArray.length = 0 -这个说法变异原tempArray因为你正在推动tempArray阵列中的groupArray ,改变tempArray反映在groupArray为好。

    You could clone the tempArray and push the copy of the tempArray in the groupArray您可以克隆tempArray并将tempArray的副本推tempArray groupArray

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

    or you could assign the new empty array to tempArray或者您可以将新的空数组分配给tempArray

     tempArray = [];
  3. When its the last iteration of the loop, you are not pushing the contents of the tempArray in the groupArray .当它是循环的最后一次迭代时,您不会将tempArray的内容推tempArray groupArray This will lead to the groupArray not containing the last number in the sorted array, ie 591 .这将导致groupArray不包含排序数组中的最后一个数字,即591 You need to check if the current iteration is the last iteration of the loop or not.您需要检查当前迭代是否是循环的最后一次迭代。 If it is, push the tempArray in the groupArray如果是,则推送tempArray中的groupArray

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

Here's a simplified version of your code:这是您的代码的简化版本:

 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);

There might be even faster approaches but I took a quick shot at it:可能有更快的方法,但我快速尝试了一下:

  • first, we break down the array into the groups首先,我们将数组分解为组
  • and then we sort not on the whole array but only on the group's key to avoid a second full iteration over the array.然后我们不是对整个数组进行排序,而是只对组的键进行排序,以避免对数组进行第二次完整迭代。

I've used a Map instead of a dictionary for the groups because we can leverage the Map.set function neatly.我为组使用了 Map 而不是字典,因为我们可以巧妙地利用 Map.set 函数。 It returns the whole Map which we need as the return value within the reduce.它返回我们需要的整个 Map 作为reduce 中的返回值。

 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);

Here you go with a more debuggable version so you can try to understand the version above:这里有一个更易于调试的版本,以便您可以尝试理解上面的版本:

 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM