最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Group duplicates values in javascript array together, then sort those groups by their value name ascending - Stack Overflow

programmeradmin4浏览0评论

I have an array of objects which I have to loop through and group duplicate values by property name "tagColor", then the grouped objects I need to sort by name. I achieved first step I sorted by color, now I need to sort only those groups by name, implementing this in angular 4, typescript

Here is array list

 tags =    [
      {
        "tagType": {
          "name": "a",
          "tagColor": "#0000FF"
        }
      },
      {

        "tagType": {
          "name": "a",
          "tagColor": "#FF0000"
        }
      },
      {

        "tagType": {
          "name": "c",
          "tagColor": "#FF0000",
        }
      },
      {
        "tagType": {
          "name": "b",
          "tagColor": "#FF0000",
        }
      },
      {
        "tagType": {
          "name": "b",
          "tagColor": "#0000FF",
        }
      }
    ]

my function that sorts by tagColor:

tags.sort((a, b) => a.tagType.tagColor.localeCompare(b.tagType.tagColor));

this groups by color only, but how also to sort those groups alphabetically?

I have an array of objects which I have to loop through and group duplicate values by property name "tagColor", then the grouped objects I need to sort by name. I achieved first step I sorted by color, now I need to sort only those groups by name, implementing this in angular 4, typescript

Here is array list

 tags =    [
      {
        "tagType": {
          "name": "a",
          "tagColor": "#0000FF"
        }
      },
      {

        "tagType": {
          "name": "a",
          "tagColor": "#FF0000"
        }
      },
      {

        "tagType": {
          "name": "c",
          "tagColor": "#FF0000",
        }
      },
      {
        "tagType": {
          "name": "b",
          "tagColor": "#FF0000",
        }
      },
      {
        "tagType": {
          "name": "b",
          "tagColor": "#0000FF",
        }
      }
    ]

my function that sorts by tagColor:

tags.sort((a, b) => a.tagType.tagColor.localeCompare(b.tagType.tagColor));

this groups by color only, but how also to sort those groups alphabetically?

Share Improve this question edited Jul 31, 2018 at 17:51 AlexFF1 asked Jul 31, 2018 at 17:46 AlexFF1AlexFF1 1,2934 gold badges25 silver badges47 bronze badges 1
  • You just need a single sort. Color is the primary key, so pare that first. If for two elements the color is the same, then the parison result should be the result of paring secondary keys. – Pointy Commented Jul 31, 2018 at 17:50
Add a ment  | 

3 Answers 3

Reset to default 7

You can use a single sort call, if the result of paring tags is 0 you pare by name:

tags.sort((a, b) => {
    let result = b.tagType.tagColor.localeCompare(a.tagType.tagColor);
    if(result == 0) {
        return a.tagType.name.localeCompare(b.tagType.name);
    }
    return result;
});

Or a more concise but less readable version:

tags.sort((a, b) =>
    b.tagType.tagColor.localeCompare(a.tagType.tagColor) // if this is 0 (aka falsy) return the other value
        || a.tagType.name.localeCompare(b.tagType.name));

Beside the given order by color, you could use a defined custom order for the color with an object which reflects the order.

For colors, not found in the object, you could take a default value to move this colors to a defined position, to the start,

(order[a.tagType.tagColor] || -Infinity) - (order[b.tagType.tagColor] || -Infinity)

to the end,

(order[a.tagType.tagColor] || Infinity) - (order[b.tagType.tagColor] || Infinity)

or inbetween.

(colorOrder[a.tagType.tagColor] || 1.5) - (colorOrder[b.tagType.tagColor] || 1.5)

var tags = [{ tagType: { name: "a", tagColor: "#0000FF" } }, { tagType: { name: "a", tagColor: "#FF0000" } }, { tagType: { name: "c", tagColor: "#FF0000" } }, { tagType: { name: "b", tagColor: "#FF0000" } }, { tagType: { name: "b", tagColor: "#0000FF" } }],
	colorOrder = { "#0000FF": 1, "#FF0000": 2 };


tags.sort((a, b) =>
    colorOrder[a.tagType.tagColor] - colorOrder[b.tagType.tagColor] ||
    a.tagType.name.localeCompare(b.tagType.name)
);

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

Compare by color first and then pare by name in the sort function. The pare function returns -1, 0, 1. If the b should e after the a then the function returns a -1 - no sort needed, if the b is equal to the a the function returns a 0 - no sort needed, if the b needs to e before the a then the function returns a 1 - sort needed. Since -1 and 0 evaluate to false and 1 evaluates to true basically the sort function is returning a true needs to be sorted or false does not need to be sorted. So if you pare by color and it needs to be sorted then we pass the colorSort value, if the color doesn't need to be sorted then we pass the nameSort value

tags.sort((a, b) => {
  let colorSort = a.tagType.tagColor.localeCompare(b.tagType.tagColor);
  let nameSort = a.tagType.name.localeCompare(b.tagType.name);
  return (colorSort)? colorSort:nameSort;
});

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论