Order Typescript by Segment / Category

Suppose we start with this original array of objects:

{vendor:"vendor1", item:"item1", price:1100, rank:0},
{vendor:"vendor1", item:"item2",price:3200, rank:0},
{vendor:"vendor1", item:"item3", price:1100, rank:0},

{vendor:"vendor2", item:"item1", price:2000, rank:0},
{vendor:"vendor2", item:"item2",price:2000, rank:0},
{vendor:"vendor2", item:"item3", price:3200, rank:0},

{vendor:"vendor3", item:"item1", price:3200, rank:0},
{vendor:"vendor3", item:"item2",price:1100, rank:0},
{vendor:"vendor3", item:"item3", price:2000, rank:0},

How can we assign ranks based on the price property within each item category in comparison to all vendors offering the same item?

Desired Output:

{vendor:"vendor1", item:"item1", price:1100, rank:1},
{vendor:"vendor1", item:"item2",price:3200, rank:3},
{vendor:"vendor1", item:"item3", price:1100, rank:1},

{vendor:"vendor2", item:"item1", price:2000, rank:2},
{vendor:"vendor2", item:"item2",price:2000, rank:2},
{vendor:"vendor2", item:"item3", price:3200, rank:3},

{vendor:"vendor3", item:"item1", price:3200, rank:3},
{vendor:"vendor3", item:"item2",price:1100, rank:1},
{vendor:"vendor3", item:"item3", price:2000, rank:2},

Answer №1

GUIDELINES:

  1. Identify unique items
  2. Divide the array into smaller arrays based on unique items and sort by price
  3. Adjust the rank for each object in every separated array
  4. Combine all arrays back together
  5. Arrange them according to vendor to restore the original sequence

let arr = [{vendor:"vendor1", item:"item1", price:1000, rank:0},
{vendor:"vendor1", item:"item2",price:3000, rank:0},
{vendor:"vendor1", item:"item3", price:1000, rank:0},
{vendor:"vendor2", item:"item1", price:2000, rank:0},
{vendor:"vendor2", item:"item2",price:2000, rank:0},
{vendor:"vendor2", item:"item3", price:3000, rank:0},
{vendor:"vendor3", item:"item1", price:3000, rank:0},
{vendor:"vendor3", item:"item2",price:1000, rank:0},
{vendor:"vendor3", item:"item3", price:2000, rank:0},]
let items = [...new Set(arr.map(o => o.item))]
let resultArr = []
items.forEach(item => {
  let filteredArr = arr.filter(o => o.item === item)
  filteredArr.sort((a,b) => (a.price > b.price) ? 1 : ((b.price > a.price) ? -1 : 0))
  for(let i = 0; i < filteredArr.length; i++){
    filteredArr[i].rank = i + 1
  }
  resultArr = resultArr.concat(filteredArr)
})
resultArr.sort((a,b) => (a.vendor > b.vendor) ? 1 : ((b.vendor > a.vendor) ? -1 : 0))
console.log(resultArr)

Answer №2

Give this a shot. The ranking is determined by the price value

var array = [{vendor:"vendor1", item:"item1", price:1000, rank:0}, {vendor:"vendor1", item:"item2",price:1000, rank:0}, {vendor:"vendor1", item:"item3", price:1000, rank:0}, {vendor:"vendor2", item:"item1", price:2000, rank:0}, {vendor:"vendor2", item:"item2",price:2000, rank:0}, {vendor:"vendor2", item:"item3", price:2000, rank:0}, {vendor:"vendor3", item:"item1", price:3000, rank:0}, {vendor:"vendor3", item:"item2",price:3000, rank:0}, {vendor:"vendor3", item:"item3", price:3000, rank:0}];
array.forEach(item => item.rank = (item.price/1000))
console.log(array)

Answer №3

To organize the grouped price values, sort them, and assign the correct index as rank.

var data = [{ vendor: "vendor1", item: "item1", price: 1100, rank: 0 }, { vendor: "vendor1", item: "item2", price: 3200, rank: 0 }, { vendor: "vendor1", item: "item3", price: 1100, rank: 0 }, { vendor: "vendor2", item: "item1", price: 2000, rank: 0 }, { vendor: "vendor2", item: "item2", price: 2000, rank: 0 }, { vendor: "vendor2", item: "item3", price: 3200, rank: 0 }, { vendor: "vendor3", item: "item1", price: 3200, rank: 0 }, { vendor: "vendor3", item: "item2", price: 1100, rank: 0 }, { vendor: "vendor3", item: "item3", price: 2000, rank: 0 }],     collection = data.reduce((r, o) => ((r[o.item] = r[o.item] || []).push(o.price), r), {});

Object.values(collection).forEach(a => a.sort((a, b) => a - b));

data.forEach(o => o.rank = collection[o.item].indexOf(o.price) + 1);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №4

If you want to organize the array based on the 'item' and 'price', you can utilize the sort method. Following that, iterate through the sorted array and give each element a 'rank' depending on whether the preceding 'item' matches the current 'item':

const arr = [{vendor:"vendor1",item:"item1",price:1100,rank:0},{vendor:"vendor1",item:"item2",price:3200,rank:0},{vendor:"vendor1",item:"item3",price:1100,rank:0},{vendor:"vendor2",item:"item1",price:2000,rank:0},{vendor:"vendor2",item:"item2",price:2000,rank:0},{vendor:"vendor2",item:"item3",price:3200,rank:0},{vendor:"vendor3",item:"item1",price:3200,rank:0},{vendor:"vendor3",item:"item2",price:1100,rank:0},{vendor:"vendor3",item:"item3",price:2000,rank:0}]

const output = arr.sort((a, b) => a.item.localeCompare(b.item) || a.price - b.price)
  .map((o, i) => {
    const prev = arr[arr.length - 1]
    const rank = prev && prev.item === o.item
                   ? prev.rank + 1
                   : 1;
                   
    return { ...o, rank }
  })

console.log(output)

Answer №5

To achieve this, you can utilize the map method.

var data = [{vendor: "vendor1", item: "item1", price: 1000, rank: 0},
{vendor: "vendor1", item: "item2", price: 3000, rank: 0},
{vendor: "vendor1", item: "item3", price: 1000, rank: 0},

{vendor: "vendor2", item: "item1", price: 2000, rank: 0},
{vendor: "vendor2", item: "item2", price: 2000, rank: 0},
{vendor: "vendor2", item: "item3", price: 3000, rank: 0},

{vendor: "vendor3", item: "item1", price: 3000, rank: 0},
{vendor: "vendor3", item: "item2", price: 1000, rank: 0},
{vendor: "vendor3", item: "item3", price: 2000, rank: 0}];
data.map(item => item.rank = (item.price / 1000))
console.log(data)

Alternatively, you can also apply the changes using the forEach method.

var data = [{vendor: "vendor1", item: "item1", price: 1000, rank: 0},
{vendor: "vendor1", item: "item2", price: 3000, rank: 0},
{vendor: "vendor1", item: "item3", price: 1000, rank: 0},

{vendor: "vendor2", item: "item1", price: 2000, rank: 0},
{vendor: "vendor2", item: "item2", price: 2000, rank: 0},
{vendor: "vendor2", item: "item3", price: 3000, rank: 0},

{vendor: "vendor3", item: "item1", price: 3000, rank: 0},
{vendor: "vendor3", item: "item2", price: 1000, rank: 0},
{vendor: "vendor3", item: "item3", price: 2000, rank: 0}];
data.forEach(item => item.rank = (item.price / 1000))
console.log(data)

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

javascript - convert a JSON string into an object without using quotation marks

Consider the following example: var mystring = `{ name: "hello", value: 1234 }` var jsonobj = JSON.parse(mystring) The code above will not output anything because the "name" and "value" keys are missing quotes. How can I parse this strin ...

Generating an order prior to payment being made by the customer

When a user selects a product and clicks the pay button, they are redirected to Stripe where a new order is created. However, if the user changes their mind and cancels the payment during the Stripe checkout process, the order has already been created. How ...

What is the best way to transfer the variant property of the material-ui TextField when using a higher-level React component?

I'm encountering difficulties with typing... Essentially, I have a wrapper React component for the @material-ui TextField but I am struggling with getting the typings correct for the variant property. Here's the main problem. Using @material-ui ...

Linking a string value to a specific data structure in TypeScript

I'm currently exploring typescript and I have a question about mapping a string value to a custom type when using templates in function calls. For instance: object.method<TypeMapper['CustomType']>([...]) In this scenario, 'Cust ...

Steps to create a toggle feature for the FAQ accordion

I am currently working on creating an interactive FAQ accordion with specific features in mind: 1- Only one question and answer visible at a time (I have achieved this) 2- When toggling the open question, it should close automatically (having trouble with ...

AngularJS does not recognize the service being referenced

I keep encountering an error in AngularJS saying that the service is not defined, even though my controller and module are properly connected: application.js: var myapp=angular.module('myApp', []); myapp.service('productService', fun ...

Is it possible that data scraping with puppeteer consistently retrieves information solely from the initial page?

I'm facing an issue while trying to extract data from a website using puppeteer. Whenever I make a request for data, it always returns the information from the first page, even if I specify a different URL. Strangely, when I manually search for the sa ...

Experiencing difficulty moving information from React form to DATA.txt file through Express

I've tried various things, but I keep encountering the same error. Changing the file path didn't seem to make a difference. The current structure of my project is as follows: {nodemodules,public,scr (containing all files including App.jsx),DATA. ...

Updating your Heroku app (Node.js) from a GitHub repository - a step-by-step guide

I attempted to deploy my React app using the following process: git status git remote add origin <repo link> git commit -m "node js" git add . Unfortunately, this method did not work for me. Can anyone provide guidance on how to update a ...

Interacting with shadow DOM elements using Selenium's JavaScriptExecutor in Polymer applications

Having trouble accessing the 'shop now' button in the Men's Outerwear section of the website with the given code on Chrome Browser (V51)'s JavaScript console: document.querySelector('shop-app').shadowRoot.querySelector ...

Having trouble getting Vuejs to work when appending an element to Fullcalender

Hi there, I am facing an issue where appending a custom button to a full calendar event is not working properly with Vue.js methods. It works fine with core JavaScript, but I really want it to work with Vue.js methods. Any ideas on how I can achieve this? ...

Establishing communication between a master process and worker processes in Node.js: A guide to verifying bidirectional communication

After coming across this particular script from the node documentation, I tried to implement it for sending messages between Master and worker processes using cluster. However, upon running the script, I encountered an issue where I could not verify the me ...

I'm having trouble customizing the appearance of a Tab Panel using the TabsAPI. The panel keeps expanding in strange ways. How can I

Trying to customize the Tabs component from MUI is proving to be a challenge. The main issue I am facing currently is: Whenever I switch between tabs, they appear to expand in size mysteriously. This behavior seems to occur only on tabs with more content ...

React Project Encounters NPM Installation Failure

I recently started delving into the world of React and experimenting with different examples. Everything was running smoothly until I attempted to start the server [npm start] and encountered an error as shown below. Despite my best efforts, I can't p ...

Wrap every character in a span tag within this text

Extracting search strings from an object obj[item].coveredText and replacing each character with a span is what I aim to achieve. Currently, I can only replace the entire search string with a single span element. Any suggestions would be greatly appreciat ...

React Timer App: The setInterval function is being reset after each render operation

I'm currently working on a straightforward timer application that will begin counting seconds when a button is clicked. To implement this, I am utilizing react hooks. import React, { useState } from 'react' function Timer() { const [sec ...

React: Content has not been refreshed

MarketEvent.tsx module is a centralized controller: import * as React from 'react'; import EventList from './EventList'; import FullReduce from './FullReduce'; import './MarketEvent.less' export default class Mark ...

Converting an array of arguments into tuples within the range of <T extends Tuple> is denoted by [T, (...args: NonNullArray<T>) => any], where each tuple represents the argument of a

Let's start with a simple function that takes a tuple as its first argument and a function whose arguments are elements of the tuple that are not null as its second argument: let first: number | null | undefined; let last: number | null | undefined; l ...

Determining the Size and Color of Squares in a Treemap Based on Content with D3.js

I encountered an issue with a treemap visualization. I came across an example that is similar to my situation, which can be viewed here: In the demo, you can see that the size of each square in the treemap is determined by the content size. However, all s ...

Escaping an equal sign in JavaScript when using PHP

I am currently working on the following code snippet: print "<TR><TD>".$data->pass_name."</TD><TD><span id='credit'>".$data->credit_left."</span></TD><TD><input type='button' val ...