An Effective Method for Extracting the Dominant Elements Across Various Rows in a Multidimensional Array

Is there an algorithm that can efficiently process the following data?

Raw data:-

var arr = [

 ["one", "two", "three", "four", "five"] ,
 ["one", "two", "three", "six", "seven"] ,
 ["one", "two", "eight", "four", "ten"]
 /* There can be more rows (arrays) */

];

Output:-

var arr2 = [

    ["one", "two"], /* these are present in most sub arrays (in this case, 3 sub arrays) */
    ["three", "four"], /* three and four are next as they occur in 2 sub arrays */
    ["five"], /* single occurrence elements are listed without a specific order */
    ["six"], 
    ["seven"],
    ["eight"],
    ["ten"]
    /* More rows may follow... */

]

Conditions:-

  1. If an element appears only once in the entire multidimensional array, it should be added to the output array (arr2) by itself. It should not be grouped with other single-instance elements. For elements that appear multiple times, they can be grouped together based on their frequency of occurrence in the multidimensional array.

Assumptions:-

  1. No repetition of elements within a subarray.

Answer №1

Unique Solution

An innovative algorithm could consist of the following three steps:

  1. Calculating the frequency of each element in every subarray of a two-dimensional array.
  2. Constructing a new two-dimensional array to group elements with the same frequency together.
  3. Arranging the subarrays of the new 2D array in descending order based on the common frequency shared by their elements within the original array.

Note: To account for non-consecutive frequencies, this new 2D array is initially represented as a sparse object before being converted into a dense array in the JavaScript implementation provided below:

function mostCommon(a) {
  var byFrequency = [], keyCount = {}, byCount = {}, k;
  /* Step 1 */
  a.map(function(x) {
    x.map(function(y) {
      if (!keyCount[y]) keyCount[y] = 1;
      else keyCount[y]++;
    });
  });
  /* Step 2 */
  for (k in keyCount) {
    if (!byCount[keyCount[k]])
      byCount[keyCount[k]] = [], byFrequency[byFrequency.length] = keyCount[k];
    byCount[keyCount[k]].push(k);
  }
  /* Step 3 */
  byFrequency.sort(function(a,b) { return b-a; });
  return byFrequency.map(function(x) { return byCount[x]; });
}
var arr = [

 ["one", "two", "three", "four", "five"] ,
 ["one", "two", "three", "six", "seven"] ,
 ["one", "two", "eight", "four", "ten"]
 /* Additional rows (arrays) can be included */

];

console.log(JSON.stringify(mostCommon(arr)));
/* [["one","two"],["three","four"],["five","six","seven","eight","ten"]] */

Updated Approach

If there is a need to handle individual elements separately from grouped ones, it's straightforward to split the final array returned accordingly. An updated version of the function includes an optional flag for this purpose, along with conditional statements for handling special cases:

function mostCommon(a, optSplitSingle) {
    var byFrequency = [], keyCount = {}, byCount = {}, i, k;
    a.map(function(x) {
        x.map(function(y) {
            if (!keyCount[y]) keyCount[y] = 1;
            else keyCount[y]++;
        });
    });
    for (k in keyCount) {
        if (!byCount[keyCount[k]]) {
            byCount[keyCount[k]] = [];
            byFrequency[byFrequency.length] = keyCount[k];
        }
        byCount[keyCount[k]].push(k);
    }
    byFrequency.sort(function(a,b) { return b-a; });
    a = byFrequency.map(function(x) { return byCount[x]; });
    if (optSplitSingle && byCount[1]) {
      for (k=a.length-1, i=0; i<byCount[1].length; i++)
        a[k++] = byCount[1][i];
    }
    return a;
}
var arr = [

 ["one", "two", "three", "four", "five"] ,
 ["one", "two", "three", "six", "seven"] ,
 ["one", "two", "eight", "four", "ten"]
 /* More rows (arrays) can be added */

];

console.log(JSON.stringify(mostCommon(arr, true)));
/* [["one","two"],["three","four"],"five","six","seven","eight","ten"] */

Answer №2

Utilize an array named count[11] to tally the occurrences of numbers 1 through 10 within all subarrays. Maintain a visited[11] array for tracking previously encountered numbers in the subarray. Simply establish the mapping "one" => 0, "two" => 1, "three" => 2 .... using a HashMap. Following this, arrange the count array to represent the sequence of words accordingly.

Answer №3

Something similar to this code snippet can be used:

var numList = [];

for(var i in arr)
{
  for(var j in arr[i])
  {
     if(arr[i][j] in numList) numList[arr[i][j]].count++;
     else numList[arr[i][j]] = { "count":1 };
  }
}

var sortedList = numList.sort(function(o1,o2)
{
   return o1.count < o2.count;
});

This would produce the following output:

[ one: { count: 3 },
  two: { count: 3 },
  three: { count: 2 },
  four: { count: 2 },
  five: { count: 1 },
  six: { count: 1 },
  seven: { count: 1 },
  eight: { count: 1 },
  ten: { count: 1 } ]

Combining rows with equal counts is a simple process. The time complexity for creating the array is O(N) due to JavaScript arrays using hashing, and O(MLogM) for sorting where N is the number of elements in 'arr' and M is the number of unique strings. Merging would have a time complexity of O(M).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Including an image in an HTML email template for sending messages

What are your suggestions for displaying the outlook compose box when a button is clicked, with the email body containing an image of a specific DIV? I've been using html2canvas to capture the image and then using mailto to open an Outlook compose mai ...

Angular does not seem to be triggering $watch for changes in arrays

Trying to activate a $watch function after a delay in Angular: Controller Information .controller('MyCtrl', ['$scope', function ($scope) { $scope.chickens = ["Jim", "Joe", "Fred"]; $scope.chickens.push("Steve"); setTimeou ...

Ways to generate a distinct identification number for every element within a component instance

I have a ReactJS component that I use in multiple instances. I'm trying to change the CSS elements of each component on click. Initially, I tried referencing the specific component element by ID, but the issue is that all instances currently share t ...

How can you display select elements from an array in Smalltalk?

Currently, I am developing a beginner's small talk program with the objective of displaying all elements of an integer array forwards and backwards. Additionally, I intend to print only those array elements that end with a specific digit. Although I ...

Using both italic and regular text in an HTML (or ASP.NET) textbox can add emphasis and enhance readability for

Is there a way to achieve this using JavaScript? For instance, if the initial text is 'Axxxxxx', I want it to be displayed in a textbox with normal style for the first letter and italic style for the rest like 'A*xxxxxx*' If the initia ...

How can we identify context menu events triggered by touch actions?

In my application, I have implemented drag-and-drop functionality for elements within an SVG element using d3-drag and d3-zoom. However, on touch-enabled devices such as IE11, Edge, and Firefox, a context menu pops up after a long press, which interferes w ...

Can someone please point out where I may have made an error in this program?

I'm having some trouble with a program that is supposed to encrypt() and decrypt() strings within parentheses, but it appears to be encrypting and decrypting not only the content inside the parentheses but also the closing parentheses and any words fo ...

Exploring collapsible data tables in Angular with Bootstrap styling

I am attempting to transform my static bootstrap data table, which displays the total count of fruits harvested in various months in an incremental manner, into a dynamic one using the JSON provided below: JSON { "fruit": [ { "fruitName": "Al ...

Remove the class upon clicking

I recently created a toggle-menu for my website that includes some cool effects on the hamburger menu icon. The issue I am facing is that I added a JavaScript function to add a "close" class when clicking on the menu icon, transforming it into an "X". Whil ...

While implementing reduce, I encountered an issue prompting the error message "Unable to access property 'others' of an undefined object"

I encountered an error while using the reduce function which states: ""Cannot read property 'others' of undefined" For reference, here is the link to the codesandbox: https://codesandbox.io/s/filter-sr3ci?file=/src/App.js:1408-153 ...

Tips for properly waiting for forkJoin.subscribe in order to access the returned values

Continuing from this previous post, I've decided to create a new post since the question in this one is different. Query - How can I ensure that the forkJoin operation completes before executing other business logic? Below is the Code Snippet export ...

Utilize Ionic and Angular to display the local storage value within a text box

I am in the process of developing an application using the Ionic framework. I am able to upload files to the server and receive a response, which I then save the file name in localstorage. However, I am facing an issue where I need to display this value in ...

Implementing additional input with Jquery causes tooltips to malfunction

I am developing a form that allows users to add as many rows as needed. Each input is being treated as an array for easy data storage in the database, which is a new concept for me. $(document).ready(function() { var maxField = 10; //Limitati ...

Invoke Ajax utilizing an Identifier

How do I add an ID to Ajax: function callAjax() { jQuery.ajax({ type: "GET", url: "topics.php?action=details&id=", cache: false, success: function(res){ jQuery('#ajaxcontent').html(res) ...

sending data from a callback to an express router

As I embark on learning node.js, I've encountered a challenging issue. In my passportAuth.js file, I create a user and have a callback to ensure the user is created successfully. The code snippet looks something like this: req.tmpPassport = {}; var ...

Converting a JSON format with JavaScript

As the data for a simple online store is extracted from a headless CMS, it is structured in the following format: [ { "id": 12312, "storeName": "Store1", "googleMapsUrl": "https://example1.com", "country": "Australia", ...

Change the background color of numbers in an array using DOM manipulation in JavaScript

Can someone assist me with the following task: 1. Generate an array containing 10 numbers ranging from 0 to 360. 2. Display these numbers on the DOM within a chosen element. 3. Adjust the background color of each number based on its HUE value in (hue, sat ...

Best practice for filling an array using a promise

I am completely new to the world of modern JavaScript. My goal is to fill an array with data that I receive from a promise in a helperService. export class PeopleTableComponent implements OnInit { people: Array < Person > = []; constructor( ...

The retrieval of JSON file using $.GetJson() is unsuccessful from local directory

There is a basic autocomplete program in place. The data entered in the textbox is successfully captured while debugging, however, the GetJson() function fails to retrieve the JSON file, causing the program to malfunction. Here's the relevant code sn ...

Error when using a third-party library in a jQuery plugin on an Android device

Currently, I am working on an application that utilizes a jQuery UI plugin, which then relies on the Raphael library. Everything runs smoothly on iOS and standard browsers, but when it comes to Android, I encounter the following error: ReferenceError: can ...