避免多次遍历数组以重新排列元素

Avoid looping over array multiple times to rearrange elements

本文关键字:新排列 排列 元素 遍历 数组      更新时间:2023-09-26

我遇到一种情况,我必须根据某些属性值重新排列对象数组,但我正在努力避免多次循环遍历数组。

      // first move the labels to the front
      entry.response.forEach( (resp, idx) => {
        if (resp.metadata.response_label && resp.metadata.response_label !== '') {
          rearrangeArray(entry.response, idx, 0);
        }
      });
      // second move the enums in front of the labels
      entry.response.forEach( (resp, idx) => {
        if (resp.metadata.response_type === "enum") {
          rearrangeArray(entry.response, idx, 0);
        }
      });

首先,如果响应枚举存在,我需要将它们移动到数组的前面。如果存在标签,则需要将它们移动到数组的前面,但在枚举类型之后。rearrangeArray函数最终也基本上循环遍历数组,因此此代码效率非常低。

是否有任何模式或 lodash 函数可以帮助优化此过程?

更新:我的rearrangeArray函数获取数组,然后是旧索引,然后是新索引(arr,old_index,new_index(

这会将数组分类为两个数组,然后连接它们。我不确定你在用 rerangeArray 做什么,所以你会使用这是一个示例而不是最终解决方案。

var labels = [];
var enums = [];
entry.response.forEach( (resp, idx) => {
  if (resp.metadata.response_label && resp.metadata.response_label !== '') {
    labels.push(resp)
    //rearrangeArray(entry.response, idx, 0);
  } else if (resp.metadata.response_type === "enum") {
    enums.push(resp)
    //rearrangeArray(entry.response, idx, 0);
  }
});
var results = labels.concat(enums)

您可以将Array.prototype.sort与自定义比较一起使用。请注意,sort不一定稳定,因此此解决方案可以更改"enum"的顺序。

function compareValues(a, b) {
  return (a > b) ? 1 : (a < b ? -1 : 0);
}
function weighItem(x) {
  var meta = x.metadata;
  if (meta.response_type === "enum") return 0;
  if (meta.response_label) return 1;
  return 2;
}
function compareResponses(a, b) {
  return compareValues(weighItem(a), weighItem(b));
}
var arr = [
  { metadata: {
    response_type: "enum",
    response_label: ""
  } },
  { metadata: {
    response_type: "not_enum",
    response_label: ""
  } },
  { metadata: {
    response_type: "enum",
    response_label: "asd"
  } },
  { metadata: {
    response_type: "not_enum",
    response_label: "fgh"
  } }
];
arr.sort(compareResponses);
// Log the output
$('pre').text(JSON.stringify(arr, null, 2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre></pre>