Как отсортировать наблюдаемый массив, содержащий объекты json?

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

Ideclare the observablearray, как yhis:

 var self =this;
 self.array= ko.observableArray();

я зацикливаюсь на массиве observablearray с именем "array" с этим кодом

self.array().forEach(function(v,i){
 alert(JSON.stringify(v))
}

его возвращает мне:

{"uuid":"74af2d36-aa47-45c5-af5d-b32c8ed56202","label":"a"}
{"uuid":"412f6222-e4c3-40a0-8a30-b1e31f53d746","label":"b"}
{"uuid":"115c9fa4-c43b-4ad0-bad7-855da850905f","label":"c"}
{"uuid":"55671032-9fc5-4361-8722-3d14abaa7d81","label":"d"}

Я действительно хочу добавить что-то подобное в мой новый observableArray:

{"uuid":"115c9fa4-c43b-4ad0-bad7-855da850905f","label":"c"}
{"uuid":"74af2d36-aa47-45c5-af5d-b32c8ed56202","label":"a"}
{"uuid":"55671032-9fc5-4361-8722-3d14abaa7d81","label":"d"}
{"uuid":"412f6222-e4c3-40a0-8a30-b1e31f53d746","label":"b"}

Всего 1 ответ


Сортировка JS 101

Для сортировки массива вы используете Array.prototype.sort . Вы передаете ему функцию, которая принимает два элемента, a и b , и возвращает 1 , -1 или 0 .

Если он возвращает 1 если a идет после b , -1 если a предшествует b , и 0 если нет разницы.

 const stringSort = (a, b) => a.localeCompare(b); const numericSort = (a, b) => a > b ? 1 : a < b ? -1 : 0; const products = [ { name: "Bread", cost: 3.10 }, { name: "Almond Milk", cost: 1.30 }, { name: "Chocolate", cost: 2.90 } ]; console.log( "By name:", products.sort((p1, p2) => stringSort(p1.name, p2.name)) ); console.log( "By cost:", products.sort((p1, p2) => numericSort(p1.cost, p2.cost)) ); 

Обратите внимание, что вы не можете передать помощников напрямую методу products.sort ! Вам нужна другая функция, которая определяет, по какому свойству мы хотим отсортировать.

Используя нокаут

Крутая вещь с нокаутом заключается в том, что вы можете создать отсортированную версию ваших данных, которая автоматически обновляется при изменении источника! Вот интерактивный пример, чтобы показать, что вы можете сделать.

В приведенном ниже примере:

  • Я сортирую в вычисляемом, так что таблица пользовательского интерфейса обновляется автоматически
    • когда вы добавляете товар
    • когда вы удаляете продукт
    • когда вы меняете метод сортировки
    • когда вы меняете направление сортировки

 const stringCompare = (a, b) => a.localeCompare(b); const numericCompare = (a, b) => a > b ? 1 : a < b ? -1 : 0; const products = ko.observableArray([ { name: "Bread", cost: 3.10 }, { name: "Almond Milk", cost: 1.30 }, { name: "Chocolate", cost: 2.90 } ]); const sorters = [ { label: "By cost", sort: (a, b) => numericCompare(a.cost, b.cost) }, { label: "Alphabetically", sort: (a, b) => stringCompare(a.name, b.name) } ]; const desc = ko.observable(true); const sorter = ko.observable(sorters[0]); const sortMethod = ko.pureComputed(() => desc() ? (a, b) => -1 * sorter().sort(a, b) : sorter().sort ) const sortedProducts = ko.pureComputed(() => products().sort(sortMethod()) ); const newProduct = { name: ko.observable(""), cost: ko.observable(0) }; const removeProduct = p => { products.remove(p); } const addProduct = () => { products.push({ name: newProduct.name(), cost: +newProduct.cost() }); newProduct.name(""); newProduct.cost(0); }; ko.applyBindings({ sorters, desc, sortedProducts, newProduct, addProduct, removeProduct }) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <div> Sort by: <select data-bind="options: sorters, value: sorter, optionsText: 'label'"></select> Descending <input type="checkbox" data-bind="checked: desc"> </div> <table> <thead> <tr> <th>no.</th> <th>Name</th> <th>Cost</th> <th></th> </tr> </thead> <tbody data-bind="foreach: sortedProducts"> <tr> <td data-bind="text: $index() + 1"></td> <td data-bind="text: name"></td> <td data-bind="text: '$' + cost.toFixed(2)"></td> <td> <button data-bind="click: $root.removeProduct">remove</button> </td> </tr> </tbody> <tbody data-bind="with: newProduct"> <tr> <td></td> <td> <input data-bind="value: name" placeholder="product name"> </td> <td> <input type="number" min="0" step="0.1" data-bind="value: cost"> </td> <td> <button data-bind="click: addProduct">add</button> </td> </tr> </tbody> </table>