-2

I thought I had this figured out but I was wrong. I'm experiencing a strange issue with sorting the key string ending with a number/digit. When I sort my data to display from highest (newest item added) to the lowest (oldest item added); it seems to sort the key string with the single numbers on top as a group, then the multiple digit numbers will underneath the single numbers. When a new location is added (new one or adding another existing location the array returns random sequence results; not adhering to the sort order, from newest to the oldest. I tried many sort methods, it will sorts but I get the same results mentioned. Below is the code I'm using to show the different location and its number of time it's listed.

My data array from the console. I am fetching the data from a SharePoint list.

Array(16) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, … ]
​
0: Object { key: "Location-9", values: 1 }
​
1: Object { key: "Location-8", values: 5 }
​
2: Object { key: "Location-7", values: 5 }
​
3: Object { key: "Location-6", values: 5 }
​
4: Object { key: "Location-5", values: 14 }
​
5: Object { key: "Location-4", values: 10 }
​
6: Object { key: "Location-3", values: 8 }
​
7: Object { key: "Location-2", values: 6 }
​
8: Object { key: "Location-16", values: 5 }
​
9: Object { key: "Location-15", values: 2 }
​
10: Object { key: "Location-14", values: 2 }
​
11: Object { key: "Location-13", values: 2 }
​
12: Object { key: "Location-12", values: 2 }
​
13: Object { key: "Location-11", values: 2 }
​
14: Object { key: "Location-10", values: 2 }
​
15: Object { key: "Location-1", values: 15 }

My script for counting the number of times the Location was added to the SharePoint list:

data = chartData;

data.sort(function (a, b) { return b.key < a.key ? -1 : 1;})

var LocationCount  = d3.nest().key(function(d) { return d.value; })
  .rollup(function(v) { return v.length; })
  .entries(data);
4
  • Does this answer your question? How to sort strings in JavaScript numerically Commented Jun 10, 2023 at 14:52
  • If the leading string is always the same than just read the number +b.key.match(/\d+/)[0] Commented Jun 10, 2023 at 15:03
  • I tried similar methods but how do I target the "key: Location-..." to fall in sequence and stay when there is an update, i.e., Location-16, Location-15, Location-14, down to Location-1? When I apply these different sort method there is no change in the order, it say the same. Commented Jun 10, 2023 at 15:04
  • Epascarello - When I updated my sort with your suggestion I get the following error. Uncaught TypeError: b.key is undefined. My update: data.sort(function (a, b) { return +b.key.match(/\d+/)[0] < a.key ? -1 : 1;}). Is this was what you were suggestion to do? Commented Jun 10, 2023 at 15:13

2 Answers 2

1

let arr = [{
    key: "Location-9",
    values: 1
  },
  {
    key: "Location-8",
    values: 5
  },
  {
    key: "Location-7",
    values: 5
  },
  {
    key: "Location-6",
    values: 5
  },
  {
    key: "Location-5",
    values: 14
  },
  {
    key: "Location-4",
    values: 10
  },
  {
    key: "Location-3",
    values: 8
  },
  {
    key: "Location-2",
    values: 6
  },
  {
    key: "Location-16",
    values: 5
  },
  {
    key: "Location-15",
    values: 2
  },
  {
    key: "Location-14",
    values: 2
  },
  {
    key: "Location-13",
    values: 2
  },
  {
    key: "Location-12",
    values: 2
  },
  {
    key: "Location-11",
    values: 2
  },
  {
    key: "Location-10",
    values: 2
  },
  {
    key: "Location-1",
    values: 15
  }
];

//id for reference for sorting purpose
arr.forEach((element) => {
  element.id = element.key.split("-")[1];
});
//sort the value from ascending;
let ascSort = arr.sort((a, b) => {
  return a.id - b.id;
});
//sort the value from descending;
let descSort = arr.sort((a, b) => {
  return b.id - a.id;
});

//deleted id not required
arr.forEach((element) => {
  delete element.id;
});



//console.log(ascSort);
console.log(descSort)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Mahadev. It worked! This seems like the best solution for what I was seeking to achieve. It handles new updates and the script don't shift when a new item is added to list, it stay in sequence. I really appreciate the help with this problem.
1

You can extract the numeric value of the key and sort by it. The extraction during sorting seems to work faster:

<script name="benchmark" data-count="1000000">
const arr=[{key:"Location-9",values:1},{key:"Location-8",values:5},{key:"Location-7",values:5},{key:"Location-6",values:5},{key:"Location-5",values:14},{key:"Location-4",values:10},{key:"Location-3",values:8},{key:"Location-2",values:6},{key:"Location-16",values:5},{key:"Location-15",values:2},{key:"Location-14",values:2},{key:"Location-13",values:2},{key:"Location-12",values:2},{key:"Location-11",values:2},{key:"Location-10",values:2},{key:"Location-1",values:15}];

// @benchmark extract keys during sorting
arr.sort((a, b) => (a.id ??= a.key.match(/\d+$/)[0]) - (b.id ??= b.key.match(/\d+$/)[0]))

// @benchmark extract keys separately
arr.forEach(item => item.id = item.key.match(/\d+$/)[0])
arr.sort((a, b) => a.id - b.id)
</script>
<script src="https://raw.githack.com/silentmantra/benchmark/master/benchmark.min.js"></script>

6 Comments

Alexander, I appreciate your solution. It also worked for me. The only issue is the Benchmark.min.js. I have to get it approved by my IT department to use and I don't have the time to wait for their approval :) But I will keep this solution on file for future use.
@TonyT you can copy my code from <script> and console.log the result manually. also the code in the snippet is executed in a iframe's sandbox and cannot harm your device in any way, the stackoverflow.com cares about that
@TonyT if you find my answer helpful you could upvote (the arrow up) or/and accept (the checkbox) my answer that way i'll be motivated to answer you in the future.
Hello Alexander will do. I should have known that :) The script can be that way. Thank you for the assist - your solution works perfect as well and solves the problem I was encountering.
@TonyT and it's strange you've accepted an answer with a slower and less elegant solution
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.