JavaScript按“组”对数组进行排序并保持顺序

时间:2020-03-31 13:09:18

标签: javascript arrays angular sorting

我有一个看起来像这样的数据集:

[
{
    "name": "Item1",
    "section": "section1",
    "total": 3,
}, {
    "name": "Item1",
    "section": "section2",
    "total": 4,
}{
    "name": "Item1",
    "section": "section3",
    "total": 7,
}, {
    "name": "Item2",
    "section": "section1",
    "total": 1,
}, {
    "name": "Item2",
    "section": "section2",
    "total": 2,
}, {
    "name": "Item2",
    "section": "section3",
    "total": 3,
    }
]

我只需要按第3节项目中的总值对数组进行排序,但要保持每个名称的顺序(第1节,第2节,然后是第3节)。因此,对于此示例,Item2应将其所有3行移到Item1上方。我尝试过按多个项目进行排序,但这并不能保持我需要的排序。我是否应该获取最小/最大的商品,抓住相关物品并将其放入新的数组中,然后重复进行操作?或者是否有更合乎逻辑的方法来实现这一目标?

如果我可以在其中利用某些东西,我还将使用角网格和定格网格。

5 个答案:

答案 0 :(得分:1)

对于name等于total的项目,我将使用section作为键并使用section3作为值来创建地图。然后,您可以使用地图进行排序。

这将按totalsection3的值对所有项目进行排序,并保留匹配排序值的原始排序顺序。

const map = new Map<string, number>(this.data
  .filter(x => x.section === 'section3')
  .map(x => [ x.name, x.total ]));

this.sorted = this.data.slice()
  .sort((a, b) => map.get(a.name) - map.get(b.name));

这确实取决于您在问题中指定的结构和排序数据。

演示:https://stackblitz.com/edit/angular-fsswdq

答案 1 :(得分:1)

您可以

  • 收集同一组的所有对象并获得总计进行排序,
  • 按组total的值排序,
  • 获取所有对象的平面数组。

const
    data = [{ name: "Item1", section: "section1", total: 3 }, { name: "Item1", section: "section2", total: 4 }, { name: "Item1", section: "section3", total: 7 }, { name: "Item2", section: "section1", total: 1 }, { name: "Item2", section: "section2", total: 2 }, { name: "Item2", section: "section3", total: 3 }],
    result = Object
        .values(data.reduce((r, o) => {
            r[o.name] = r[o.name] || { payload: [] };
            r[o.name].payload.push(o);
            if (o.section === 'section3') r[o.name].total = o.total;
            return r;
        }, {}))
        .sort(({ total: a }, { total: b }) => a - b)
        .flatMap(({ payload }) => payload);

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

答案 2 :(得分:0)

var array = [
{
    "name": "Item1",
    "section": "section1",
    "total": 3,
}, {
    "name": "Item1",
    "section": "section2",
    "total": 4,
},{
    "name": "Item1",
    "section": "section3",
    "total": 7,
}, {
    "name": "Item2",
    "section": "section1",
    "total": 1,
}, {
    "name": "Item2",
    "section": "section2",
    "total": 2,
}, {
    "name": "Item2",
    "section": "section3",
    "total": 3,
    }
];

array = array.sort((o1, o2)=>{

if(o1.section === o2.section && o1.section === 'section3') {
   return o1.total - o2.total;
} else {
  return o1.section === 'section3' ? 1 : -1;
}
});

console.log(array);

这是输出

[
  {
    "name": "Item1",
    "section": "section1",
    "total": 3
  },
  {
    "name": "Item1",
    "section": "section2",
    "total": 4
  },
  {
    "name": "Item2",
    "section": "section1",
    "total": 1
  },
  {
    "name": "Item2",
    "section": "section2",
    "total": 2
  },
  {
    "name": "Item2",
    "section": "section3",
    "total": 3
  },
  {
    "name": "Item1",
    "section": "section3",
    "total": 7
  }
]

答案 3 :(得分:0)

您首先需要按name对数据集进行“分组”,然后按total进行排序。

let items = [{
  "name": "Item1",
  "section": "section1",
  "total": 3,
}, {
  "name": "Item1",
  "section": "section2",
  "total": 4,
}, {
  "name": "Item1",
  "section": "section3",
  "total": 7,
}, {
  "name": "Item2",
  "section": "section1",
  "total": 1,
}, {
  "name": "Item2",
  "section": "section2",
  "total": 2,
}, {
  "name": "Item2",
  "section": "section3",
  "total": 3,
}];

let groups = {};

for (let item of items) {
  if (!groups[item.name]) {
    groups[item.name] = {
      data: []
    };
  }

  // Grouping by `name`
  groups[item.name].data.push(item);

  // Store the `total`
  if (item.section == "section3") {
    groups[item.name].key = item.total;
  }
}

// sort the groups, this will maintain the order of sections (1,2 and 3) in each group
let sortedGroups = Object.values(groups).sort((a, b) => {
  return a.key - b.key; // ascending
});

// then flatten the groups
let flatten = [].concat(...sortedGroups.map(x => x.data));

console.log(flatten);

答案 4 :(得分:0)

优先级排序

const data = [{"name":"Item1","section":"section1","total":3},{"name":"Item1","section":"section2","total":4},{"name":"Item1","section":"section3","total":7},{"name":"Item2","section":"section1","total":1},{"name":"Item2","section":"section2","total":2},{"name":"Item2","section":"section3","total":3}];
console.log(
  data.sort((a, b) => {
    const diff = a.total - b.total;
    if (diff) return diff;
    return b.section.localeCompare(a.section);
  })
);
.as-console-row {color: blue!important}