将重复项组织成有序的单个数组

时间:2019-04-11 09:35:34

标签: javascript arrays

我有一个数字数组。我想按顺序排列数字,并在同一数组(数组中的数组)中创建重复的新数组。有人可以帮我一步一步。我真的很想了解

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

// I want to create this [[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591]

const sortArray = arr.sort(function(a, b) {
        return a - b;
    });

7 个答案:

答案 0 :(得分:5)

您可以使用Set提取唯一值,然后对其进行排序(因为对数组数组进行排序比较复杂),然后使用array.reduce获取原始数组中的所有项目并按唯一的值(如果唯一),否则为值的数组(不确定为什么需要它,但是仍然..)

更多文档参考:

下面的工作代码:

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

// I want to create this [[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591]

console.log([...new Set(arr)].sort((a,b) => a - b).reduce((accumulator, next) => {
	const filtered = arr.filter(i => i === next);
  return accumulator.push(filtered.length === 1 ? filtered[0] : filtered), accumulator
}, []));

答案 1 :(得分:1)

您可以对数组进行排序,并查看最后两个项目和实际项目。

[   1,   1,   1,   1,   2,   2,   2,   4,   5,  10,  20,  20, 391, 392, 591] array
                   a    b    c                                               variables
                             ^                                               actual item

然后检查最后一项b和实际项目c是否不相等,并返回包含旧项目和实际项目的新数组。

如果最后一个项目a之前的项目与实际项目不相等,则它应该是结果集中最后一个项目和实际项目的数组。

否则将实际项目推送到结果集的嵌套最后一个数组中。

var array = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20],
    result = array
        .sort((a, b) => a - b)
        .reduce((r, c, i, { [i - 2]: a, [i - 1]: b }) => {
             if (b !== c) return [...r, c];
             if (a !== c) return r.pop(), [...r, [b, c]];
             r[r.length - 1].push(c);
             return r;
        }, []);

console.log(result);

答案 2 :(得分:0)

尽管还有其他方法,但是每当我需要以这种方式解析数组的唯一值时,我都会创建一个对象,该对象的属性代表数组值的分组

{ 1: [1, 1, 1], 2: [2 , 2, 2], 4: [4], 5: [5] ...}

然后,您可以根据需要使用本机对象方法来获取对象的所有键或值(或者,如果最终目标不同,则可以使用需要的对象)

Object.keys(obj)
// or
Object.values(obj)

对于您的情况,看起来像

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

const obj = arr.reduce((accum, val) => {
    accum[val] = accum[val] || [];
    accum[val].push(val);
    return accum;
}, {});

const finalArr = Object.values(obj).map(val => val.length > 1 ? val : val[0]);
console.log(finalArr);

答案 3 :(得分:0)

您可以先使用reduce,然后再使用Array.fill。在这里reduce将创建一个像这样的对象

{
  "1": 4,
  "2": 3,
  "4": 1,
  "5": 1,
  "10": 1,
  "20": 2,
  "391": 1,
  "392": 1,
  "591": 1
}

表示4 1s3 2s,依此类推。然后,您可以在迭代此对象后使用数组填充。数组fill的语法为arr.fill(value[, start[, end]])

因此,在我们的情况下,我们将假设new Array(k[keys]).fill(+keys, 0, k[keys])正在创建一个长度为43的新数组,以此类推,除了1之外,从第0个索引开始填充钥匙

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

let k = arr.reduce(function(acc, curr) {
  if (curr in acc) {
    acc[curr] += 1;
  } else {
    acc[curr] = 1
  }

  return acc;
}, {});

let grouped = [];
for (let keys in k) {
  if (k[keys] !== 1) {
    grouped.push(new Array(k[keys]).fill(+keys, 0))
  } else {
    grouped.push(+keys)
  }
}
console.log(grouped)

答案 4 :(得分:0)

您可以计算发生的次数,然后使用该对象创建最终数组。

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

const count = arr.reduce((acc, val) => {

  acc[val] = acc[val] + 1 || 1;

  return acc;
}, {});

const result = Object
  .keys(count)
  .sort((a, b) => a - b)
  .map((key) => count[key] === 1 ? +key : Array.from({ length: count[key] }).fill(+key));

console.log(result);

答案 5 :(得分:0)

您可以通过多种方式执行此操作。但是,如果要以最佳方式实现,则必须避免 n个正方形循环
因此可以创建一个值计数字典。并按排序顺序遍历对象的键。

使用Array.reduce创建数组元素数量的对象。和Array.fill来过滤具有相同值的数组。

//Given Array
const arr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];

   //Dictionary with count of each values in array
const arrCountObj = arr.reduce((acc, el) => {
  if (acc[el]) {
    acc[el] += 1
  } else {
    acc[el] = 1
  }
  return acc
}, {})
console.log(arrCountObj)
   //Looping over sorted dictionary keys to create array based on condition
var out = Object.keys(arrCountObj).sort((a, b) => a - b).map(x => arrCountObj[x] > 1 ? new Array(arrCountObj[x]).fill(+x) : arrCountObj[x])

console.log(out)

  

时间复杂度:O(nlogn)

答案 6 :(得分:0)

您可以:

1)遍历数组以构建数字的频率图

2)抓住并按升序对频率映射键进行排序

3)根据频率图中的信息构建一个新的阵列

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

const obj = arr.reduce((acc, c) => {
  return acc[c] = (acc[c] || 0) + 1, acc;
}, {});

// {"1":4,"2":3,"4":1,"5":1,"10":1,"20":2,"391":1,"392":1,"591":1}

const keys = Object.keys(obj).sort((a, b) => a - b).map(Number);

// [1,2,4,5,10,20,391,392,591]

const out = keys.map((key) => {
  return obj[key] > 1 ? Array(obj[key]).fill(key) : key;
});

// [[1,1,1,1],[2,2,2],4,5,10,[20,20],391,392,591]

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