按内容类型对对象排序

时间:2018-08-15 07:16:35

标签: javascript object

如何按内容类型对对象排序?

const myObject = {
    "id": 3,
    "name": "my object",
    "content": ["a", "b", "c"],
    "description": "my description",
    "anotherArray": [11, 22, 33],
    "contentObject": {
        "id": 56,
        "name": "content object"
    }
}

我希望排序顺序为:

  1. 数值
  2. 字符串
  3. 数组
  4. 对象
  5. 还有什么

我找到了Sorting JavaScript Object by property value,但是我正在寻找按内容类型而不是内容值进行排序的方法。

到目前为止,我已经...

const getDefaultTypeValue = (value) => {

    const val = value;
    let newVal = null;

    const isString =    (value) => (typeof value === 'string' || value instanceof String);
    const isNumber =    (value) => (typeof value === 'number' && isFinite(value));
    const isArray =     (value) => (Array.isArray(value));
    const isFunction =  (value) => (typeof value === 'function');
    const isNull =      (value) => (value === null);
    const isUndefined = (value) => (typeof value === 'undefined');
    const isBoolean =   (value) => (typeof value === 'boolean');
    const isDate =      (value) => (value instanceof Date);
    const isRegExp =    (value) => (value && typeof value === 'object' && value.constructor === RegExp);
    const isError =     (value) => (value instanceof Error && typeof value.message !== 'undefined');
    const isSymbol =    (value) => (typeof value === 'symbol');

    if (isString(val)) {
        newVal = '';
    } else if (isNumber(val)) {
        newVal = null;
    } else if (isArray(val)) {
        newVal = [];
    } else if (isFunction(val)) {
        newVal = val;
    } else if (isUndefined(val)) {
        newVal = undefined;
    } else if (isBoolean(val)) {
        newVal = false;
    } else if (isDate(val)) {
        newVal = new Date();
    } else if (isRegExp(val)) {
        newVal = '';
    } else if (isError(val)) {
        newVal = null;
    } else if (isSymbol(val)) {
        newVal = null;
    } else if (isNull(val)) {
        newVal = null;
    }

    return newVal;
}

但是我真的想不起来该怎么实现。

预期输出:

const myObject = {
    "id": 3,
    "name": "my object",
    "description": "my description",
    "content": ["a", "b", "c"],
    "anotherArray": [11, 22, 33],
    "contentObject": {
        "id": 56,
        "name": "content object"
    }
}

3 个答案:

答案 0 :(得分:1)

因此,首先不要像这样对对象进行排序;这使整个操作有些困难-但是,您可以对对象键进行排序。为此,这与按字母顺序或按字母排序键相同。创建一个数组,以所需的顺序进行检查,并使用索引

        Reduced data availability: 128 pgs inactive, 128 pgs incomplete
const checks = [
  isNumber,
  isString,
  isArray,
  isPlainSybol,
  isFunction,
  isNull,
  isUndefined,
  isBoolean,
  isDate,
  isRegExp,
  isError,
  isSymbol
];

const myObject = {
  "id": 3,
  "name": "my object",
  "content": ["a", "b", "c"],
  "description": "my description",
  "anotherArray": [11, 22, 33],
  "contentObject": {
    "id": 56,
    "name": "content object"
  }
}

const sortedKeys = Object.keys(myObject).sort((a,b) =>
   checks.findIndex(e => e(myObject[a])) - checks.findIndex(e => e(myObject[b]))
 )

console.log(sortedKeys);

答案 1 :(得分:1)

如注释中所述,对象没有排序,因此您无法对对象进行排序。您可以 对数组进行排序。如果要排序,则需要一个可比较的值。换句话说,您需要确定一个值是大于,小于还是等于另一个。最简单的方法是为每种类型分配一个数字,该数字表示排序顺序和基于该顺序的排序。例如,下面是一个简单(不完整)的函数,用于将类型映射到数字:

function sortValue(item) {
  let order  = {
    'number': 3,
    'string': 2,
    'object': 0
  }
  if (Array.isArray(item)) return 1
  else if (typeof item in order) return order[typeof item]
  else return -1
}

这样,您可以对值(或基于值的键等)进行排序。当然,这会返回一个数组,因为与对象不同的数组是有序的:

const myObject = {
  "id": 3,
  "name": "my object",
  "content": ["a", "b", "c"],
  "description": "my description",
  "anotherArray": [11, 22, 33],
  "contentObject": {
    "id": 56,
    "name": "content object"
  }
}

function sortValue(item) {
  let order = {
    'number': 3,
    'string': 2,
    'object': 0
  }
  if (Array.isArray(item)) return 1
  else if (typeof item in order) return order[typeof item]
  else return -1
}

let sortedValues = Object.values(myObject).sort((a, b) => sortValue(b) - sortValue(a))

console.log(sortedValues)

答案 2 :(得分:1)

Ypou8可以通过检查类型来重建对象,并使用数字值(索引)进行排序。未知类型会排序到数组的末尾以重建对象。

function rebuildObject(object) {
    const
        isNumber = v => typeof v === 'number' && isFinite(v),
        isString = v => typeof v === 'string' || v instanceof String,
        isArray = v => Array.isArray(v),
        isObject = v => v && typeof v === 'object',
        getOrder = v => [isNumber, isString, isArray, isObject].findIndex(fn => fn(v)) + 1 || Infinity;

    return Object.assign(
        ...Object
            .entries(object)
            .sort(({ 1: a }, { 1: b }) => getOrder(a) - getOrder(b))
            .map(([k, v]) => ({ [k]: v }))
    );
}

console.log(rebuildObject({ id: 3, name: "my object", content: ["a", "b", "c"], description: "my description", anotherArray: [11, 22, 33], contentObject: { id: 56, name: "content object" } }));
.as-console-wrapper { max-height: 100% !important; top: 0; }