Подсчет вхождений / частоты элементов массива - PullRequest
184 голосов
/ 14 апреля 2011

В Javascript я пытаюсь взять начальный массив числовых значений и сосчитать элементы внутри него.В идеале, результатом должны быть два новых массива, первый из которых определяет каждый уникальный элемент, а второй содержит количество раз, которое встречается каждый элемент.Однако я открыт для предложений по формату вывода.

Например, если начальный массив был:

5, 5, 5, 2, 2, 2, 2, 2, 9, 4

Тогда будут созданы два новых массива.Первый будет содержать имя каждого уникального элемента:

5, 2, 9, 4

Второй будет содержать число раз, которое элемент встречался в исходном массиве:

3, 5, 1, 1

Поскольку число 5 происходиттри раза в исходном массиве число 2 встречается пять раз, а 9 и 4 появляются один раз.

Я много искал решение, но, похоже, ничего не работает, и все, что я пробовал самв итоге оказался нелепо сложным.Любая помощь будет оценена!

Спасибо:)

Ответы [ 35 ]

0 голосов
/ 03 мая 2016

Вот классический метод старой школы для подсчета массивов.

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var counted = [], count = [];
var i = 0, j = 0, k = 0;
while (k < arr.length) {
    if (counted.indexOf(arr[k]) < 0) {
        counted[i] = arr[k];
        count[i] = 0;
        for (j = 0; j < arr.length; j++) {
            if (counted[i] == arr[j]) {
                count[i]++;
            }
        }
        i++;
    } else {
        k++;
    }
}

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

0 голосов
/ 29 сентября 2015

Заданный массив x т.е. x = ['boy','man','oldman','scout','pilot']; количество вхождений элемента 'man' равно

x.length - x.toString().split(',man,').toString().split(',').length ;
0 голосов
/ 03 июля 2017

Вот способ подсчета вхождений внутри массива объектов. Он также помещает содержимое первого массива в новый массив для сортировки значений, чтобы порядок в исходном массиве не нарушался. Затем используется рекурсивная функция для прохождения каждого элемента и подсчета свойства количества каждого объекта в массиве.

var big_array = [
  { name: "Pineapples", quantity: 3 },
  { name: "Pineapples", quantity: 1 },
  { name: "Bananas", quantity: 1 },
  { name: "Limes", quantity: 1 },
  { name: "Bananas", quantity: 1 },
  { name: "Pineapples", quantity: 2 },
  { name: "Pineapples", quantity: 1 },
  { name: "Bananas", quantity: 1 },
  { name: "Bananas", quantity: 1 },
  { name: "Bananas", quantity: 5 },
  { name: "Coconuts", quantity: 1 },
  { name: "Lemons", quantity: 2 },
  { name: "Oranges", quantity: 1 },
  { name: "Lemons", quantity: 1 },
  { name: "Limes", quantity: 1 },
  { name: "Grapefruit", quantity: 1 },
  { name: "Coconuts", quantity: 5 },
  { name: "Oranges", quantity: 6 }
];

function countThem() {
  var names_array = [];
  for (var i = 0; i < big_array.length; i++) {
    names_array.push( Object.assign({}, big_array[i]) );
  }

  function outerHolder(item_array) {
    if (item_array.length > 0) {
      var occurrences = [];
      var counter = 0;
      var bgarlen = item_array.length;
      item_array.sort(function(a, b) { return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0); });

      function recursiveCounter() {
        occurrences.push(item_array[0]);
        item_array.splice(0, 1);
        var last_occurrence_element = occurrences.length - 1;
        var last_occurrence_entry = occurrences[last_occurrence_element].name;
        var occur_counter = 0;
        var quantity_counter = 0;
        for (var i = 0; i < occurrences.length; i++) {
          if (occurrences[i].name === last_occurrence_entry) {
            occur_counter = occur_counter + 1;
            if (occur_counter === 1) {
              quantity_counter = occurrences[i].quantity;
            } else {
              quantity_counter = quantity_counter + occurrences[i].quantity;
            }
          }
        }

        if (occur_counter > 1) {
          var current_match = occurrences.length - 2;
          occurrences[current_match].quantity = quantity_counter;
          occurrences.splice(last_occurrence_element, 1);
        }

        counter = counter + 1;

        if (counter < bgarlen) {
          recursiveCounter();
        }
      }

      recursiveCounter();

      return occurrences;
    }
  }
  alert(JSON.stringify(outerHolder(names_array)));
}
0 голосов
/ 04 января 2017

Существует гораздо лучший и простой способ сделать это, используя ramda.js. Пример кода здесь

const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary) countBy документация находится на документация

0 голосов
/ 04 апреля 2017

Что касается моего комментария, спрашивающего @Emissary о корректировке его решения. я добавляю способ, которым я обработал это:

let distinctArr = yourArray.filter((curElement, index, array) => array.findIndex(t =>    t.prop1=== curElement.prop1 && t.prop2 === curElement.prop2 && t.prop3=== curElement.prop3) === index);
let distinctWithCount = [...new Set(distinctArr)].map(function(element){element.prop4 = yourArray.filter(t =>    t.prop1=== element.prop1 && t.prop2 === element.prop2 && t.prop2=== element.prop2).length;

То, что я здесь делаю, - это сначала удалить дубликаты и сохранить массив (diverArr), затем рассчитать на исходный массив (yourArray) количество времени, в течение которого объект был продублирован, и добавить 4-е свойство со значением вхождений

Надеюсь, это поможет кому-то, кто нуждается в этом конкретном решении. Ofc сделано с ES6

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...