【问题标题】:I have an array of numbers. I need to return a new array in which the duplicate numbers are in their own nested array我有一个数字数组。我需要返回一个新数组,其中重复的数字在它们自己的嵌套数组中
【发布时间】:2019-08-08 20:42:35
【问题描述】:

我需要获取这个数组 [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20] 并返回一个新数组,它将所有重复的数字排序到它们自己的嵌套数组中.

它应该返回 [[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591]。

我搞砸了 for 循环以及 .map() 方法,似乎无法找到解决方案。在这一点上,我几乎只是在黑暗中拍摄,希望能有所作为。我是 javascript 的新手。

const cleaner = array1.map((num, index, array) => {
    if (array1.indexOf(num) >= index) {
        return num;
    } else {
        return array;
    }
    });

【问题讨论】:

  • 如果有人让你用笔和纸来做,你会怎么做?作为一个小小的提示,显示的结果数组不仅被排序为数组,而且还按数字排序——这是一个很好的指标,表明这是你可以做的第一件事,然后从那里开始。

标签: javascript arrays


【解决方案1】:

您可以使用Set 收集唯一值,然后使用Array.prototype.map()Array.prototype.filter() 为每个值创建子数组。

const array = [1,2,4,591,392,391,2,5,10,2,1,1,1,20,20];

// defines a function that...
const arrange = array =>
  // creates array of unique values
  Array.from(new Set(array))
  // sorts unique values in ascending order
  .sort((a, b) => a - b)
  // creates a subarray for each unique value
  .map(key => array.filter(value => key === value))
  // unwraps unit length subarrays
  .map(subarray => subarray.length === 1 ? subarray[0] : subarray);

const cleaner = arrange(array);

console.log(JSON.stringify(cleaner));

这不是最有效的方法,但它比使用reduce() 方法的过程方法更具可读性(在我看来),并且对于这种长度的数组,执行时间的差异可以忽略不计。

【讨论】:

    【解决方案2】:

    您可以使用reduce 执行此操作,请参阅 sn-p 中的 cmets:

    const arr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
    
    const result = arr.reduce((acc, curr) => {
    
      // check if the element exists in the accumulator
      const ndx = acc.findIndex(e => (Array.isArray(e) ? e.includes(curr) : e === curr));
    
      if (ndx === -1) {
        // if it doesn't exist, push it
        acc.push(curr);
      } else {
        // if it exists, check if it's an array
        if (Array.isArray(acc[ndx])) acc[ndx].push(curr); // if it is, push the current element
        else acc[ndx] = [acc[ndx], curr]; // convert the current element in accumulator to an array with the previous and the new elements
      }
      return acc;
    }, []);
    
    console.log(result);

    【讨论】:

      【解决方案3】:

      为此,您需要执行一些操作:

      1. 计算每个数字的出现次数。
      2. 对不重复的数字进行排序。
      3. 将其映射为具有数字(非重复)或重复数字数组。
      const array = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
      

      步骤 1

      让我们计算项目。为此,我将创建一个对象来跟踪每个对象。

      const counted = array.reduce(
          (acc, current) => Object.assign(acc, { [current]: acc[current] ? acc[current] += 1 : 1 }),
          {}
      );
      

      使用 reduce 我们创建了一个对象,它看起来像这样:

      {
          '1': 5,
          '2': 3,
          '4': 1,
          '5': 1,
          // etc.
      }
      

      第二步

      让我们对元素进行排序:

      const sorted = Object.keys(counted)
          .map(Number) // <-- we have to remember that object keys are strings
          .sort((a, b) => a - b);
      

      第三步

      现在我们已经准备好带有计数的对象并对其进行排序,让我们将它们放在一起。如果counted 中的数字是1,那么我们直接插入值,否则我们将其转换为值数组。

      const final = sorted.map(
          (number) => counted[number] == 1
              ? number
              : Array.from({ length: counted[number] }, () => number)
      );
      

      【讨论】:

        【解决方案4】:

        您可以获取一个对象并使用隐式排序。

        var array = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20],
            result = Object.values(array.reduce((r, v) => {
                if (v in r) r[v] = [].concat(r[v], v);
                else r[v] = v;
                return r;
            }, {}));
        
        console.log(result);

        【讨论】:

          猜你喜欢
          • 2018-08-23
          • 1970-01-01
          • 2014-12-27
          • 2018-02-10
          • 1970-01-01
          • 2018-09-10
          • 2019-07-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多