Working with Typescript to map and sort the key values of a new datasource object

Managing a large datasource filled with objects can be challenging. My goal is to rearrange the order of objects in the array based on new values for each key. Whenever a new value for a key is found, I want the corresponding object to move to the top of the array. This way, the top elements in the array will always represent the different values that properties can have.

arr[0] = {name: john, age: 14, address: xxx}
arr[1] = {name: john, age: 14, address: xxx}
arr[2] = {name: marie, age: 14, address: xxx}
arr[3] = {name: marie, age: 14, address: xxx}
arr[4] = {name: john, age: 15, address: xxx}

The desired outcome would look like this:

arr[0] = {name: john, age: 14, address: xxx}
arr[1] = {name: marie, age: 14, address: xxx}
arr[2] = {name: john, age: 15, address: xxx}
arr[3] = {name: marie, age: 14, address: xxx}
arr[4] = {name: john, age: 14, address: xxx}

This example is simplified as the actual dataset may vary in keys, quantity, and values. To dynamically achieve this reordering, I am currently iterating through all objects, identifying new values for each key, storing them in an array of unique values, and moving the current object to the top of the array based on these new values. The process repeats for each object containing a new key value.

filterDS(dataSource){

    let uniqueColumns;
    let i = 0;
    let j = 0;
    let temp;
    dataSource.forEach(data => {
      let keys = Object.keys(data);
      keys.forEach( key => {
        console.log(key + ":" + data[key]);
        uniqueColumns[key].push(data[key]);
        temp = dataSource[i];
        j = dataSource.indexOf(data);
        dataSource[i] = dataSource[j];
        dataSource[j] = temp;
        i++
      })
    });
    return dataSource;
  }

However, I seem to encounter issues when trying to read undefined values. I have attempted to check for empty datasource, key values, and even the current object, but the problem persists. It seems to break when encountering an undefined or empty field. I am unsure of what mistake I might be making here.

Answer №1

To move ahead, consider grouping by the name initially and then looping through the longest group to access each other grouped array by index.

const arr = [{ name: 'john', age: 14, adress: 'xxx' }, { name: 'john', age: 14, adress: 'xxx' }, { name: 'marie', age: 14, adress: 'xxx' }, { name: 'marie', age: 14, adress: 'xxx' }, { name: 'john', age: 15, adress: 'xxx' }, { name: 'tim', age: 15, adress: 'xxx' },];

// Grouping by object.name
const tempMap = {};
for (const o of arr) {
  (tempMap[o.name] ??= []).push(o);
}
const groups = Object.values(tempMap);

// Finding the length of the longest grouped array
const maxLen = Math.max(...groups.map(o => o.length))

const result = [];
// Looping through the longest array to access each grouped array by index
for (let i = 0; i < maxLen; i++) {
  for (const arr of groups) {
    if (i < arr.length) {
      result.push(arr[i]);
    }
  }
}

console.log(result);

Alternatively, create a more generic function that takes a callback to specify the property/ies to group by and an optional sorting function for arranging the grouped arrays before mapping to the result.

function filterDS(dataSource, getProp, sortFn) {
  // Use the provided callback to group-by
  const tempMap = {};
  for (const o of dataSource) {
    (tempMap[getProp(o)] ??= []).push(o);
  }
  const groups = Object.values(tempMap);

  // Sort the groups if a custom sort function is provided
  if (typeof sortFn === 'function') {
    groups.sort(sortFn);
  }

  // Find the length of the longest grouped array
  const maxLen = Math.max(...groups.map(o => o.length))

  const result = [];
  // Iterate through the longest array while accessing each grouped array by index
  for (let i = 0; i < maxLen; i++) {
    for (const arr of groups) {
      if (i < arr.length) {
        result.push(arr[i]);
      }
    }
  }

  return result
}

const arr = [{ name: 'beth', age: 14, adress: 'xxx' }, { name: 'andrew', age: 14, adress: 'xxx' }, { name: 'carrie', age: 14, adress: 'xxx' }, { name: 'xeno', age: 15, adress: 'xxx' }, { name: 'carrie', age: 14, adress: 'xxx' }, { name: 'andrew', age: 15, adress: 'xxx' }, { name: 'andrew', age: 15, adress: 'xxx' },];

console.log(filterDS(arr, (o) => o.name, (a, b) => a[0].name.localeCompare(b[0].name))); // Sorted alphabetically ascending
console.log(filterDS(arr, (o) => o.name)); // Not sorted

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

Removing a dynamic TypeScript object key was successful

In TypeScript, there is a straightforward method to clone an object: const duplicate = {...original} You can also clone and update properties like this: const updatedDuplicate = {...original, property: 'value'} For instance, consider the foll ...

Firestore - Insert new entries into an array in an existing document using Typescript

After retrieving data from Firestore using Firebase and implementing pagination function, I encounter an issue when attempting to add the new values to an array. Specifically, TypeScript raises an error message when I try to invoke the setState hook. int ...

a method for inserting a space after a certain character, with the exception of when that character is located at the start or end of a line

I've created a regular expression that can modify various patterns like: anything1 * anything2* anything3 anything1* anything2 * anything3 anything1 * anything2 * anything3 anything1*anything2 *anything3 anything1 * anything2 *anything3 anything1*any ...

In the Vercel production environment, when building Next.js getStaticPaths with URL parameters, the slashes are represented as %

I've encountered an issue while implementing a nextjs dynamic route for my static documentation page. Everything works perfectly in my local environment, and the code compiles successfully. However, when I try to access the production URL, it doesn&ap ...

Encountering a tuple type TypeScript error with a spread argument is far too frequent an occurrence

Encountering this error is becoming a frequent occurrence for me, and I am currently unable to resolve it. src/graphics.ts:105:55 - error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter. 105 _queue.forEach((_ ...

The persistence of postback from the javascript function despite returning false when utilizing Asp Radiobuttonlist

HTML: <asp:RadioButtonList ID="rdStatus" runat="server" Height="48px" RepeatDirection="Horizontal" AutoPostBack="true" OnSelectedIndexChanged="rdStatus_SelectedIndexChanged" CssClass="rad"> ...

Trouble with the navigation of the JavaScript image gallery: next and previous buttons are not

Is it possible to have multiple galleries on a single page with captions? I've been trying to incorporate this JavaScript code, but struggling to make the next/previous links function for both galleries. Since I'm new to JavaScript, any advice or ...

I am having trouble accessing the input field in my AngularJS controller

Having an issue with my Ionic framework setup using AngularJS. I am unable to access the input field "groupName" in my controller, as it always returns "undefined". I was under the impression that using ng-model would automatically add it to the controlle ...

Utilizing Multiple Checkboxes for Precision Search Refinement

Big thanks to Khalid Ali for the support provided up until now. I am currently working with an array of songs that each have descriptions, keywords, etc. I have a set of checkboxes that I want to use to refine a search. Essentially, if someone selects the ...

Preserving the video's aspect ratio by limiting the width and height to a maximum of 100%

I am trying to integrate a YouTube video using their embed code in a "pop-up". However, I am facing an issue where the video does not resize to fit within the height of its parent. I want it to be constrained by the div#pop-up that contains the video. Curr ...

Having trouble using the `.not` function in jQuery

I'm working on implementing a collapsible menu using jQuery. When any header is clicked, the next sibling (the box) should expand while all other boxes collapse. HTML <div class="finbox" id="finbox1"> <div class="finheader" id="finheade ...

Turn off error notifications from eslint parsing

Within my code, there is a conditional export that looks like this: if (process.env.NODE_ENV === 'testing') export myFunc; While in es6, this type of statement is typically not allowed due to the requirement for imports and exports to be top- ...

Unable to load the threejs module

I am still learning about threejs and have mostly worked on projects using a dev server (vite) locally. This setup limited me to accessing my projects only from the browser on my computer. Here is how I typically include my files in these projects: <bod ...

Issue encountered when exporting with node and mongoose

After creating some schema and exporting the model, here is the code: var mongoose = require('mongoose'); var specSchema = new mongoose.Schema({ name: String, description:String }); var qualSchema = new mongoose.Schema({ name: Str ...

Using Yii to attach an onclick event to CLinkPager for every pager link

Is there a way to execute a function with every pager link click in Yii's CLinkPager? I've tried the following code without success. 'pagerCssClass' => 'pagination', 'afterAjaxUpdate'=>"FB.Canvas.scrollTo ...

What is the best way to toggle the visibility of fields on a modal in a Ruby on Rails

I am working on an application that utilizes Rails 4.1 and Ruby 2.1.2. The show.html.erb view for the Assignment Model in this application is as follows: <h1><%= "#{'Source URL'}"%> <div class="source-url"><%= @assignment.so ...

What is the method for retrieving an array or object that contains a collection of files designated for uploading within the jQuery file upload plugin?

Currently, I have successfully integrated a form into my Rails site and set up the jQuery file upload plugin. The upload form functions properly with the ability to select multiple files and utilize all ajax upload features. However, a challenge I am faci ...

failure to render updated content after modification of variable

I am facing an issue with triggering a function in the component: componentA.ts html = 'hey'; this.onElementSelected(r => this.change()); public change() { console.log(this.html); if (this.html === 'hey&ap ...

Creating a declaration file for a library's entry point involves outlining the structure and types

I have developed an npm library that is made up of several ES6 modules, which are then consolidated into a single js file. The directory structure looks like this: src main.ts one.ts two.ts three.ts types index.d.ts index.ts The index.ts fil ...

Easily automate button clicks on a new tab website

Seeking assistance below, following codes are sourced from "example.com" as assumed: <a href="http://www.example.org" target="vo1" onclick="gp(1)" rel="nofollow">Click Me</a> Upon clicking on ...