Как я могу переупорядочить объект javascript на основе порядка массива? [Дубликат]

320
задан Peter David Carter 17 May 2016 в 10:15
поделиться

23 ответа

Это работает для меня

/**
 * Return an Object sorted by it's Key
 */
var sortObjectByKey = function(obj){
    var keys = [];
    var sorted_obj = {};

    for(var key in obj){
        if(obj.hasOwnProperty(key)){
            keys.push(key);
        }
    }

    // sort keys
    keys.sort();

    // create new array based on Sorted Keys
    jQuery.each(keys, function(i, key){
        sorted_obj[key] = obj[key];
    });

    return sorted_obj;
};
25
ответ дан Ashit Vora 25 August 2018 в 20:02
поделиться

Решение:

function getSortedObject(object) {
  var sortedObject = {};

  var keys = Object.keys(object);
  keys.sort();

  for (var i = 0, size = keys.length; i < size; i++) {
    key = keys[i];
    value = object[key];
    sortedObject[key] = value;
  }

  return sortedObject;
}

// Test run
getSortedObject({d: 4, a: 1, b: 2, c: 3});

Объяснение:

Многие версии JavaScript сохраняют значения внутри объекта в том порядке, в котором они добавлены.

Чтобы отсортировать свойства объекта по их клавишам, вы можете использовать функцию Object.keys , которая вернет массив ключей. Затем массив ключей можно отсортировать с помощью метода Array.prototype.sort () , который сортирует элементы массива на месте (нет необходимости назначать их новой переменной).

После сортировки ключей вы можете использовать их один за другим, чтобы получить доступ к содержимому старого объекта, чтобы заполнить новый объект (который теперь отсортирован).

Ниже приведен пример (вы можете проверить его в целевых браузерах):

/**
 * Returns a copy of an object, which is ordered by the keys of the original object.
 *
 * @param {Object} object - The original object.
 * @returns {Object} Copy of the original object sorted by keys.
 */
function getSortedObject(object) {
  // New object which will be returned with sorted keys
  var sortedObject = {};

  // Get array of keys from the old/current object
  var keys = Object.keys(object);
  // Sort keys (in place)
  keys.sort();

  // Use sorted keys to copy values from old object to the new one
  for (var i = 0, size = keys.length; i < size; i++) {
    key = keys[i];
    value = object[key];
    sortedObject[key] = value;
  }

  // Return the new object
  return sortedObject;
}

/**
 * Test run
 */
var unsortedObject = {
  d: 4,
  a: 1,
  b: 2,
  c: 3
};

var sortedObject = getSortedObject(unsortedObject);

for (var key in sortedObject) {
  var text = "Key: " + key + ", Value: " + sortedObject[key];
  var paragraph = document.createElement('p');
  paragraph.textContent = text;
  document.body.appendChild(paragraph);
}

Примечание: Object.keys метод ECMAScript 5.1, но здесь это полиполк для старых браузеров:

if (!Object.keys) {
  Object.keys = function (object) {
    var key = [];
    var property = undefined;
    for (property in object) {
      if (Object.prototype.hasOwnProperty.call(object, property)) {
        key.push(property);
      }
    }
    return key;
  };
}
2
ответ дан Benny Neugebauer 25 August 2018 в 20:02
поделиться

Вот чистая версия на основе lodash, которая работает с вложенными объектами

/**
 * Sort of the keys of an object alphabetically
 */
const sortKeys = function(obj) {
  if(_.isArray(obj)) {
    return obj.map(sortKeys);
  }
  if(_.isObject(obj)) {
    return _.fromPairs(_.keys(obj).sort().map(key => [key, sortKeys(obj[key])]));
  }
  return obj;
};

. Было бы даже более чистым, если бы у lodash был метод toObject() ...

3
ответ дан BlueRaja - Danny Pflughoeft 25 August 2018 в 20:02
поделиться

Использование lodash будет работать:

some_map = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' }

// perform a function in order of ascending key
_(some_map).keys().sort().each(function (key) {
  var value = some_map[key];
  // do something
});

// or alternatively to build a sorted list
sorted_list = _(some_map).keys().sort().map(function (key) {
  var value = some_map[key];
  // return something that shall become an item in the sorted list
}).value();

Просто пища для размышлений.

16
ответ дан Brian M. Hunt 25 August 2018 в 20:02
поделиться

Сортирует ключи рекурсивно, сохраняя ссылки.

function sortKeys(o){
    if(o && o.constructor === Array)
        o.forEach(i=>sortKeys(i));
    else if(o && o.constructor === Object)
        Object.entries(o).sort((a,b)=>a[0]>b[0]?1:-1).forEach(e=>{
            sortKeys(e[1]);
            delete o[e[0]];
            o[e[0]] = e[1];
        });
}

Пример:

let x = {d:3, c:{g:20, a:[3,2,{s:200, a:100}]}, a:1};
let y = x.c;
let z = x.c.a[2];
sortKeys(x);
console.log(x); // {a: 1, c: {a: [3, 2, {a: 1, s: 2}], g: 2}, d: 3}
console.log(y); // {a: [3, 2, {a: 100, s: 200}}, g: 20}
console.log(z); // {a: 100, s: 200}
0
ответ дан brunettdan 25 August 2018 в 20:02
поделиться

Чистый ответ JavaScript для сортировки объекта. Это единственный ответ, который, как я знаю, будет обрабатывать отрицательные числа. Эта функция предназначена для сортировки числовых объектов.

Вход obj = {1000: {}, -1200: {}, 10000: {}, 200: {}};

function osort(obj) {
var keys = Object.keys(obj);
var len = keys.length;
var rObj = [];
var rK = [];
var t = Object.keys(obj).length;
while(t > rK.length) {
    var l = null;
    for(var x in keys) {
        if(l && parseInt(keys[x]) < parseInt(l)) {
            l = keys[x];
            k = x;
        }
        if(!l) { // Find Lowest
            var l = keys[x];
            var k = x;
        }
    }
    delete keys[k];
    rK.push(l);
}

for (var i = 0; i < len; i++) {

    k = rK[i];
    rObj.push(obj[k]);
}
return rObj;
}

Выход будет отсортирован по объекту по тем номерам с новыми ключами, начинающимися с 0.

1
ответ дан Case 25 August 2018 в 20:02
поделиться

Многие люди отмечают, что «объекты нельзя сортировать», но после этого они дают вам решение, которое работает. Парадокс, не так ли?

Никто не упоминает, почему эти решения работают. Они есть, потому что в большинстве реализаций браузера значения в объектах хранятся в том порядке, в котором они были добавлены. Поэтому, если вы создаете новый объект из отсортированного списка ключей, он возвращает ожидаемый результат.

И я думаю, что мы могли бы добавить еще одно решение - функциональный способ ES5:

function sortObject(obj) {
    return Object.keys(obj).sort().reduce(function (result, key) {
        result[key] = obj[key];
        return result;
    }, {});
}

Версия ES2015 выше (отформатирована на «однострочный»):

function sortObject(o) {
    return Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {});
}

Краткое объяснение приведенных выше примеров (как указано в комментариях):

Object.keys дает нам список ключей в предоставленном объекте (obj или o), то мы сортируем тех, кто использует алгоритм сортировки по умолчанию, следующий .reduce используется для преобразования этого массива обратно в объект, но на этот раз со всеми ключами отсортированы.

121
ответ дан codename- 25 August 2018 в 20:02
поделиться

Возможно, немного более элегантная форма:

 /**
     * Sorts a key-value object by key, maintaining key to data correlations.
     * @param {Object} src  key-value object
     * @returns {Object}
     */
var ksort = function ( src ) {
      var keys = Object.keys( src ),
          target = {};
      keys.sort();
      keys.forEach(function ( key ) {
        target[ key ] = src[ key ];
      });
      return target;
    };


// Usage
console.log(ksort({
  a:1,
  c:3,
  b:2  
}));

P.S. и то же самое с синтаксисом ES6 +:

function ksort( src ) {
  const keys = Object.keys( src );
  keys.sort();
  return keys.reduce(( target, key ) => {
        target[ key ] = src[ key ];
        return target;
  }, {});
};
8
ответ дан Dmitry Sheiko 25 August 2018 в 20:02
поделиться

Отличный проект by @sindresorhus, называемый sort-keys, который работает потрясающе.

Здесь вы можете проверить его исходный код:

https://github.com / sindresorhus / sort-keys

Или вы можете использовать его с npm:

$ npm install --save sort-keys

Вот примеры кода из его readme

const sortKeys = require('sort-keys');

sortKeys({c: 0, a: 0, b: 0});
//=> {a: 0, b: 0, c: 0}

sortKeys({b: {b: 0, a: 0}, a: 0}, {deep: true});
//=> {a: 0, b: {a: 0, b: 0}}

sortKeys({c: 0, a: 0, b: 0}, {
    compare: (a, b) => -a.localeCompare(b)
});
//=> {c: 0, b: 0, a: 0}
2
ответ дан fernandopasik 25 August 2018 в 20:02
поделиться

Underscore version :

function order(unordered)
{
return _.object(_.sortBy(_.pairs(unordered),function(o){return o[0]}));
}

Если вы не доверяете браузеру сохранению порядка ключей, я настоятельно рекомендую полагаться на упорядоченный массив ключей -value парные массивы.

_.sortBy(_.pairs(c),function(o){return o[0]})
8
ответ дан Flavien Volken 25 August 2018 в 20:02
поделиться
2
ответ дан Flimzy 25 August 2018 в 20:02
поделиться

Другие ответы на этот вопрос устарели, никогда не соответствовали реальности реализации и официально стали некорректными, когда была опубликована спецификация ES6 / ES2015.


См. раздел о [1] Все методы, которые перебирают ключи свойств, делают это в том же порядке:

  1. Сначала все Индексы массивов, отсортированные численно.
  2. Затем все строковые ключи (которые не являются индексами) в том порядке, в котором они были созданы.
  3. Затем все символы в том порядке, в котором они

Итак, да, объекты JavaScript фактически упорядочены, а порядок их ключей / свойств может быть изменен.

Вот как вы может сортировать объект по его ключам / свойствам, в алфавитном порядке:

const unordered = {
  'b': 'foo',
  'c': 'bar',
  'a': 'baz'
};

console.log(JSON.stringify(unordered));
// → '{"b":"foo","c":"bar","a":"baz"}'

const ordered = {};
Object.keys(unordered).sort().forEach(function(key) {
  ordered[key] = unordered[key];
});

console.log(JSON.stringify(ordered));
// → '{"a":"baz","b":"foo","c":"bar"}'

Используйте var вместо const для совместимости с двигателями ES5.

264
ответ дан infiniteluke 25 August 2018 в 20:02
поделиться

Простой и читаемый фрагмент, используя lodash.

Вам нужно поместить ключ в кавычки только при вызове sortBy. Это не должно быть в кавычках в самих данных.

_.sortBy(myObj, "key")

Кроме того, ваш второй параметр для карты неверен. Это должна быть функция, но проще использовать pluck.

_.map( _.sortBy(myObj, "key") , "value");
2
ответ дан JLavoie 25 August 2018 в 20:02
поделиться

Чтобы упростить его и дать более ясный ответ от Matt Ball

//your object
var myObj = {
    b : 'asdsadfd',
    c : 'masdasaf',
    a : 'dsfdsfsdf'
  };

//fixed code
var keys = [];
for (var k in myObj) {
  if (myObj.hasOwnProperty(k)) {
    keys.push(k);
  }
}
keys.sort();
for (var i = 0; i < keys.length; i++) {
  k = keys[i];
  alert(k + ':' + myObj[k]);
}

1
ответ дан João Pimentel Ferreira 25 August 2018 в 20:02
поделиться

Просто используйте lodash для распаковки карты и sortBy первое значение пары и zip снова вернет отсортированный ключ.

Если вы хотите, чтобы параметр сортировки изменил значение пары на 1 вместо 0

var o = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' };
console.log(_(o).toPairs().sortBy(0).fromPairs().value())

3
ответ дан Narayanaperumal Gurusamy 25 August 2018 в 20:02
поделиться

Объекты JavaScript1 не упорядочены. Бесполезно пытаться «сортировать» их. Если вы хотите перебрать свойства объекта, вы можете отсортировать ключи, а затем получить связанные значения:

var myObj = {
    'b': 'asdsadfd',
    'c': 'masdasaf',
    'a': 'dsfdsfsdf'
  },
  keys = [],
  k, i, len;

for (k in myObj) {
  if (myObj.hasOwnProperty(k)) {
    keys.push(k);
  }
}

keys.sort();

len = keys.length;

for (i = 0; i < len; i++) {
  k = keys[i];
  alert(k + ':' + myObj[k]);
}


Alternate Object.keys fanciness:

var myObj = {
    'b': 'asdsadfd',
    'c': 'masdasaf',
    'a': 'dsfdsfsdf'
  },
  keys = Object.keys(myObj),
  i, len = keys.length;

keys.sort();

for (i = 0; i < len; i++) {
  k = keys[i];
  alert(k + ':' + myObj[k]);
}


1Не быть педантичным, но нет объекта JSON .

224
ответ дан Paolo Moretti 25 August 2018 в 20:02
поделиться

Используйте этот код, если у вас есть вложенные объекты или у вас есть вложенный массив obj.

var sortObjectByKey = function(obj){
    var keys = [];
    var sorted_obj = {};
    for(var key in obj){
        if(obj.hasOwnProperty(key)){
            keys.push(key);
        }
    }
    // sort keys
    keys.sort();

    // create new array based on Sorted Keys
    jQuery.each(keys, function(i, key){
        var val = obj[key];
        if(val instanceof Array){
            //do for loop;
            var arr = [];
            jQuery.each(val,function(){
                arr.push(sortObjectByKey(this));
            }); 
            val = arr;

        }else if(val instanceof Object){
            val = sortObjectByKey(val)
        }
        sorted_obj[key] = val;
    });
    return sorted_obj;
};
2
ответ дан Phani Reddy 25 August 2018 в 20:02
поделиться

Предположим, что это может быть полезно в отладчике VisualStudio, который показывает неупорядоченные свойства объекта.

(function(s){var t={};Object.keys(s).sort().forEach(function(k){t[k]=s[k]});return t})({b:2,a:1,c:3})
11
ответ дан Serg 25 August 2018 в 20:02
поделиться

Это старый вопрос, но, отвечая на вопрос Матиаса Биненса, я сделал короткую версию для сортировки текущего объекта без особых накладных расходов.

    Object.keys(unordered).sort().forEach(function(key) {
        var value = unordered[key];
        delete unordered[key];
        unordered[key] = value;
    });

после выполнения кода , сам «неупорядоченный» объект будет иметь сортировку по алфавиту.

17
ответ дан Sergio Moura 25 August 2018 в 20:02
поделиться

Я перенес некоторые перечисления Java в javascript-объекты.

Эти объекты вернули мне правильные массивы. если объектные ключи являются смешанными типами (строка, int, char), возникает проблема.

var Helper = {
    isEmpty: function (obj) {
        return !obj || obj === null || obj === undefined || Array.isArray(obj) && obj.length === 0;
    },

    isObject: function (obj) {
        return (typeof obj === 'object');
    },

    sortObjectKeys: function (object) {
        return Object.keys(object)
            .sort(function (a, b) {
                c = a - b;
                return c
            });
    },
    containsItem: function (arr, item) {
        if (arr && Array.isArray(arr)) {
            return arr.indexOf(item) > -1;
        } else {
            return arr === item;
        }
    },

    pushArray: function (arr1, arr2) {
        if (arr1 && arr2 && Array.isArray(arr1)) {
            arr1.push.apply(arr1, Array.isArray(arr2) ? arr2 : [arr2]);
        }
    }
};

function TypeHelper() {
    var _types = arguments[0],
        _defTypeIndex = 0,
        _currentType,
        _value;

    if (arguments.length == 2) {
        _defTypeIndex = arguments[1];
    }

    Object.defineProperties(this, {
        Key: {
            get: function () {
                return _currentType;
            },
            set: function (val) {
                _currentType.setType(val, true);
            },
            enumerable: true
        },
        Value: {
            get: function () {
                return _types[_currentType];
            },
            set: function (val) {
                _value.setType(val, false);
            },
            enumerable: true
        }
    });

    this.getAsList = function (keys) {
        var list = [];
        Helper.sortObjectKeys(_types).forEach(function (key, idx, array) {
            if (key && _types[key]) {

                if (!Helper.isEmpty(keys) && Helper.containsItem(keys, key) || Helper.isEmpty(keys)) {
                    var json = {};
                    json.Key = key;
                    json.Value = _types[key];
                    Helper.pushArray(list, json);
                }
            }
        });
        return list;
    };

    this.setType = function (value, isKey) {
        if (!Helper.isEmpty(value)) {
            Object.keys(_types).forEach(function (key, idx, array) {
                if (Helper.isObject(value)) {
                    if (value && value.Key == key) {
                        _currentType = key;
                    }
                } else if (isKey) {
                    if (value && value.toString() == key.toString()) {
                        _currentType = key;
                    }
                } else if (value && value.toString() == _types[key]) {
                    _currentType = key;
                }
            });
        } else {
            this.setDefaultType();
        }
        return isKey ? _types[_currentType] : _currentType;
    };

    this.setTypeByIndex = function (index) {
        var keys = Helper.sortObjectKeys(_types);
        for (var i = 0; i < keys.length; i++) {
            if (index === i) {
                _currentType = keys[index];
                break;
            }
        }
    };

    this.setDefaultType = function () {
        this.setTypeByIndex(_defTypeIndex);
    };

    this.setDefaultType();
}


var TypeA = {
    "-1": "Any",
    "2": "2L",
    "100": "100L",
    "200": "200L",
    "1000": "1000L"
};

var TypeB = {
    "U": "Any",
    "W": "1L",
    "V": "2L",
    "A": "100L",
    "Z": "200L",
    "K": "1000L"
};
console.log('keys of TypeA', Helper.sortObjectKeys(TypeA));//keys of TypeA ["-1", "2", "100", "200", "1000"]

console.log('keys of TypeB', Helper.sortObjectKeys(TypeB));//keys of TypeB ["U", "W", "V", "A", "Z", "K"]

var objectTypeA = new TypeHelper(TypeA),
    objectTypeB = new TypeHelper(TypeB);

console.log('list of objectA = ', objectTypeA.getAsList());
console.log('list of objectB = ', objectTypeB.getAsList());

Types:

var TypeA = {
    "-1": "Any",
    "2": "2L",
    "100": "100L",
    "200": "200L",
    "1000": "1000L"
};

var TypeB = {
    "U": "Any",
    "W": "1L",
    "V": "2L",
    "A": "100L",
    "Z": "200L",
    "K": "1000L"
};


Sorted Keys(output):

Key list of TypeA -> ["-1", "2", "100", "200", "1000"]

Key list of TypeB -> ["U", "W", "V", "A", "Z", "K"]
2
ответ дан Sherali Turdiyev 25 August 2018 в 20:02
поделиться

здесь 1 лайнер

var data = { zIndex:99,
             name:'sravan',
             age:25, 
             position:'architect',
             amount:'100k',
             manager:'mammu'


  };
console.log(Object.entries(data).sort().reduce( (o,[k,v]) => (o[k]=v,o), {} ));

8
ответ дан sravan kumar ganji 25 August 2018 в 20:02
поделиться

Как уже упоминалось, объекты неупорядочены.

Однако ...

Вы можете найти эту идиому полезной:

var o = { 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' };

var kv = [];

for (var k in o) {
  kv.push([k, o[k]]);
}

kv.sort()

Затем вы можете выполнить итерацию через kv и делать все, что вы пожелаете.

> kv.sort()
[ [ 'a', 'dsfdsfsdf' ],
  [ 'b', 'asdsad' ],
  [ 'c', 'masdas' ] ]
3
ответ дан Steven Keith 25 August 2018 в 20:02
поделиться

рекурсивная сортировка для вложенных объектов и массивов

function sortObjectKeys(obj){
    return Object.keys(obj).sort().reduce((acc,key)=>{
        if (Array.isArray(obj[key])){
            acc[key]=obj[key].map(sortObjectKeys);
        }
        if (typeof obj[key] === 'object'){
            acc[key]=sortObjectKeys(obj[key]);
        }
        else{
            acc[key]=obj[key];
        }
        return acc;
    },{});
}

// test it
sortObjectKeys({
    telephone: '069911234124',
    name: 'Lola',
    access: true,
    cars: [
        {name: 'Family', brand: 'Volvo', cc:1600},
        {
            name: 'City', brand: 'VW', cc:1200, 
            interior: {
                wheel: 'plastic',
                radio: 'blaupunkt'
            }
        },
        {
            cc:2600, name: 'Killer', brand: 'Plymouth',
            interior: {
                wheel: 'wooden',
                radio: 'earache!'
            }
        },
    ]
});
6
ответ дан user3286817 25 August 2018 в 20:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: