Организовать дубликаты в отдельный упорядоченный массив

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
2
задан Mebin Joe 11 April 2019 в 11:44
поделиться

6 ответов

Вы можете извлечь уникальные значения, используя 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
}, []));
[ 1113]
0
ответ дан briosheje 11 April 2019 в 11:44
поделиться

Хотя существуют и другие подходы, всякий раз, когда мне нужно разобрать уникальные значения из массива таким образом, я создам объект со свойствами объекта, представляющими группировки значений массива

{ 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);
0
ответ дан Katherine R 11 April 2019 в 11:44
поделиться

Вы можете:

1) перебрать массив, построить карту частот из чисел

2) взять и отсортировать ключ карты частот в порядке возрастания

[116 ] 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));

0
ответ дан Andy 11 April 2019 в 11:44
поделиться

Вы можете сделать это разными способами. Но если вы хотите добиться наилучших результатов, вы должны избегать 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)

0
ответ дан Ashish 11 April 2019 в 11:44
поделиться

Вы можете сосчитать вхождения и затем использовать этот объект для создания вашего окончательного массива.

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

0
ответ дан Alex G 11 April 2019 в 11:44
поделиться

Вы можете использовать reduce, а затем Array.fill. Здесь редукция создаст объект, подобный этому

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

, что означает, что есть 4 1s, 3 2s и так далее. Затем вы можете использовать заполнение массива после итерации этого объекта. Синтаксис массива fill имеет вид arr.fill(value[, start[, end]])

. Таким образом, в нашем случае new Array(k[keys]).fill(+keys, 0, k[keys]) будет создан новый массив длины 4, 3 и т. Д., За исключением 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)

0
ответ дан brk 11 April 2019 в 11:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: