【问题标题】:How to group multiple sets of duplicate integers in an array into their own array of arrays?如何将数组中的多组重复整数分组到自己的数组中?
【发布时间】:2019-06-19 21:01:57
【问题描述】:

我正在尝试通过重复值将整数数组拆分为数组数组。原始数组由 6 位整数的列表组成,其中一些整数成对出现,另一些则以 3 或 4 个一组的形式出现。我想将这些重复项推送到它们自己的数组中,并将所有这些重复项数组组合成一个数组数组,以便以后循环遍历。

我在 lodash 库中查看了一些方法或组合,但找不到任何似乎有效的方法。我还尝试了一些带有嵌套 for 循环的不同配置,但我也在为此苦苦挣扎。

const directory = "X/";
let files = fs.readdirSync(directory);
let first6Array = [ ];
for(i=0; i< files.length; i++){
 let first6 = files[i].substring(0, 6);
 first6Array.push(first6);
};
console.log(first6Array);

first6Array 的示例输出: ['141848', '141848', '141848', '142851', '142851', '143275', '143275']

我想最终得到类似的东西

让 MasterArray = [[141848,141848,141848],[142851,142851],[143275,143275]];

【问题讨论】:

  • 如果以后出现同样的数字,你期望会发生什么;例如如果first6Array = ['1', '1', '2', '1'],预期的行为是什么?
  • 不应该出现我从中绘制的数据集应该先按升序排序。

标签: javascript arrays node.js duplicates lodash


【解决方案1】:

您可以使用new Set() 过滤掉重复项。 然后使用唯一的数组并过滤每个值。

const firstArray = [ '141848', '141848', '141848', '142851', '142851', '143275', '143275'];
const numberArray = firstArray.map(Number);
const masterArray = [];

const unique = new Set (numberArray); // Set {141848, 142851, 143275}
unique.forEach(u => {
  masterArray.push(numberArray.filter(e => e === u));
});

console.log(masterArray);

【讨论】:

    【解决方案2】:

    使用lodash,你可以用flow创建一个函数:

    1. map truncating 他们的项目并转换为数字。
    2. groupBy 值(默认值)。
    3. 使用values转换为数组数组。

    const { flow, partialRight: pr, map, truncate, groupBy, values } = _;
    
    const truncate6 = s => truncate(s, { length: 6, omission: '' });
    
    const fn = flow(
      pr(map, flow(truncate6, Number)),
      groupBy,
      values,
    );
    
    const firstArray = [ '141848abc', '141848efg', '141848hij', '142851klm', '142851opq', '143275rst', '143275uvw'];
    
    const result = fn(firstArray);
    
    console.log(result);
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案3】:

      使用reduce创建一个数组对象,按数字索引,并在每次迭代时推送到关联的数组(如果需要,首先在键处创建数组),然后获取对象的值:

      const directory = "X/";
      const files = fs.readdirSync(directory);
      const output = Object.values(
        files.reduce((a, file) => {
          const num = Number(file.slice(0, 6));
          if (!a[num]) a[num] = [];
          a[num].push(num);
          return a;
        }, {})
      );
      

      但是,拥有一个相同值的数组是很奇怪的——你可能会考虑一个不同的数据结构,比如

      {
        '141848': 3,
        '142851': 2
      }
      

      跟踪每个数字的出现次数:

      const output = files.reduce((a, file) => {
        const num = file.slice(0, 6);
        a[num] = (a[num] || 0) + 1;
        return a;
      }, {})
      

      【讨论】:

        【解决方案4】:

        要获得你想要的结果,你需要一个嵌套的find,这样的东西应该可以工作:

        const directory = "X/";
        let files = fs.readdirSync(directory);
        
        let first6Array = files.reduce((acc, value)=> {
          let n = +value.substr(0, 6); // assumes it can't be NaN
          let arr = acc.find(nested => nested.find(item => item === n));
        
          if (arr) {
            arr.push(n);
          } else {
            acc.push([n]);
          }
          return acc;
        }, []);
        
        console.log(first6Array);
        

        请注意,使用值和出现次数的哈希图会更好,在性能方面也是如此,但我认为它并不介意,因为您的元素非常少。

        此外,它假定前六个字符实际上是数字,否则转换将失败,您将得到NaN

        添加检查以跳过这种情况会更安全:

        let n = +value.substr(0, 6);
        if (isNaN(n)) {
          return acc;
        }
        // etc
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-18
          • 1970-01-01
          • 2016-12-11
          相关资源
          最近更新 更多