数组对象内的key需要按照指定顺序排序,应该怎么排呢

huyouooo
  • 22

按照 arr = [b,d,a,c] 中的顺序变为result
转换前:

    let options = [{
      id: 'a',
      name: '北京'
  }, {
      id: 'b',
      name: '上海'
  }, {
      id: 'c',
      name: '深圳'
  }, {
      id: 'd',
      name: '杭州'
  }];

转换后

  let result = [{
    id: 'b',
    name: '上海'
  },
    {
      id: 'd',
     name: '杭州'
},
    {
      id: 'a',
      name: '北京'
},
    {
      id: 'c',
      name: '深圳'
}]
回复
阅读 1.9k
5 个回答
let options = [{
  id: 'a',
  name: '北京'
}, {
  id: 'b',
  name: '上海'
}, {
  id: 'c',
  name: '深圳'
}, {
  id: 'd',
  name: '杭州'
}];

let order = ['b', 'd', 'a', 'c'].reduce((result, name, index) => {
  result[name] = index;
  return result;
}, {});

// 原数组排序
options.sort((next, prev) => {
  return order[next.id] > order[prev.id] ? 1 : -1;
});

// 新数组,如果确定排序的是所有数据的话
const result = new Array(4);
options.map((item) => {
   result[order[item.id]] = item;
});

@miganzi 的更直接一些,好像我第N次看到类似的问题了,所以我贴一个间接的办法吧。

// 用于将数组中的数据按指定的方式转换为map,可选参数itemKey用于直接转换为键值对。
function buildMapByArray<T = {[key:string]: any}, U = any>(list: T[] = [], primaryKey: string | ((row: T) => string) = 'id', itemKey?: string): { [key: string]: T | U } {
    const mapping = {};
    list.forEach(item => {
        const key = typeof (primaryKey) === 'string' ? item[primaryKey] : primaryKey(item);
        if (typeof (mapping[key]) !== 'undefined') {
            throw 'Duplicate primary key: ' + key;
        }
        mapping[key] = itemKey ? item[itemKey] : item;
    });
    return mapping;
}

然后,对于你的要求

const map = buildMapByArray('id', options);
const sorted = [];
arr.map(key => map[key] && sorted.push(map[key]));
let options = [{
    id: 'a',
    name: '北京'
}, {
    id: 'b',
    name: '上海'
}, {
    id: 'c',
    name: '深圳'
}, {
    id: 'd',
    name: '杭州'
}];
const arr = ['c', 'b', 'd', 'a']
const newarr = arr.map(item=>options[options.findIndex(element=>element.id==item)])
console.log(newarr)
[
  { id: 'c', name: '深圳' },
  { id: 'b', name: '上海' },
  { id: 'd', name: '杭州' },
  { id: 'a', name: '北京' }
]
const arr = ["b", "d", "a", "c"];
const result = [...options].sort((a, b) => arr.indexOf(a.id) - arr.indexOf(b.id));
console.dir(result);
let options = [
    { id: "a", name: "北京" },
    { id: "b", name: "上海" },
    { id: "c", name: "深圳" },
    { id: "d", name: "杭州" }
];

function sortBy(data, idOrder) {
    const orderMap = Object.fromEntries(idOrder.map((id, i) => [id, i]));
    return data.sort((a, b) => orderMap[a.id] - orderMap[b.id]);
}

const r = sortBy(options, ["b", "d", "a", "c"]);
console.log(r);

另外一种情况代码如下,虽然现在跑出来可能是预期的结果,但得不到保证(好像规范没有说会保证对象的属性顺序)

// 懒得写函数了,看代码示意就好
const r2 = [
    { a: "0.89", b: "45", c: "77", d: "67" },
    { a: "546", b: "7", c: "8", d: "8" },
    { a: "78", b: "7", c: "9", d: "6" },
    { a: "0.5", b: "gg", c: "ert", d: "wer" },
].map(it => Object.fromEntries(["b", "d", "a", "c"].map(key => [key, it[key]])));
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏