如何对包含json对象的可观察数组进行排序?

时间:2019-05-15 09:36:53

标签: knockout.js

你好,我是淘汰赛javascript的新手,我有一个observablearray包含json objets。因此,我尝试按给定顺序对objets列表进行排序。

声明像yhis这样的observablearray:

 var self =this;
 self.array= ko.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 个答案:

答案 0 :(得分:0)

JS排序101

要对数组进行排序,请使用Array.prototype.sort。您为它传递了一个函数,该函数需要两个项ab,并返回1-10

如果1在{em>之后 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方法!您需要另一个函数来定义我们要对哪个属性进行排序。

使用淘汰赛

具有剔除功能的很酷的事情是,您可以创建数据的排序版本,该版本可以在源发生更改时自动更新!这是一个互动示例,展示您可以做什么。

在下面的示例中:

  • 我在计算机内部排序,以便UI的表自动更新
    • 添加产品时
    • 移除产品时
    • 更改排序方式时
    • 更改排序方向时

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>