【问题标题】:Sort and Merge Array排序和合并数组
【发布时间】:2019-01-23 21:11:39
【问题描述】:

我必须合并两个数组并根据比较按创建的值排序。我不想使用任何内置的 js 函数,例如 sort。我尝试使用 while 循环,但无法找出确切的解决方案。这是我的示例代码:

function merge(a, b, n, m)  
{  
    res = []; 
    i = 0; j = 0; k = 0;  
    while(i < n && j < m) {
        if(a[i]['created'] < b[j]['created']) {
            res.push(a[i]);
            i++;
        } else {
            res.push(b[j]);
            j++;
        }        
    }

    while(i < n) {
        res.push(a[i]);
        i++;
    }

    while(j < m) {
        res.push(b[j]);
        j++;
    }
    return res;  
}  

a = [{'title':'title1', 'created':'18'},{'title':'title2', 'created':'16'},{'title':'title3', 'created':'20'}];  
b = [{'title':'title4','created':'17'},{'title':'title5','created':'19'}];  
n = a.length;  
m = b.length;  

var endResult = merge(a, b, n, m);  
console.log(endResult);

我的预期输出应该如下:

[{'title':'title2', 'created':'16'},{'title':'title4','created':'17'},{'title':'title1', 'created':'18'},{'title':'title5','created':'19'},{'title':'title3', 'created':'20'}];

请让我知道我在这里错过了什么。

注意:我不想使用像 sort() 这样的内置 Javascript 函数。我必须根据特定的业务逻辑对值进行排序,我将在弄清楚基本排序后实现。

【问题讨论】:

  • 这是某种采访“用algs难倒你”的问题吗?你为什么不使用任何专业人士都会使用的功能呢?
  • @TimConsolazio 我的最终结果不仅仅是一个排序数组。我必须实现许多其他条件进行排序。只是我坚持基本的排序部分。
  • 我可以注意到的第一个问题是,您只是将数组a 的元素与数组b 的元素进行比较。您还需要比较属于同一数组的元素。
  • @GaneshBabu 听起来像是 XY 问题的介绍。
  • 编写sort 例程很简单。有很多 BubbleSorts、QuickSorts、TimSorts、MergeSorts 等在线示例。虽然您可以轻松地编写您自己的其中一个版本,但它很可能不会提供使用提供给内置 sort 的自定义比较器编写代码的功能。您甚至可以在merge 步骤中重用该比较器。自定义 sort 仅在您将其作为学习练习时才有意义。

标签: javascript html arrays sorting


【解决方案1】:

一个简单的 O(n^2) 解决方案是遍历所有元素以寻找最小值,然后再次遍历它们以寻找第二低的值,等等。

function mergeSort(a, b) {
    var array = a.concat(b);
    var length = array.length;
    var results = [];
    while(results.length < length) {
	var currentLowest = 0;
	for(var i = 1; i < array.length; i++) {
	    if(array[i].created < array[currentLowest].created) {
		currentLowest = i;
	    }
	}
	results.push(array[currentLowest]);
	array.splice(currentLowest,1);
    }
    return results;
}

a = [{'title':'title1', 'created':'18'},{'title':'title2', 'created':'16'},{'title':'title3', 'created':'20'}];  
b = [{'title':'title4','created':'17'},{'title':'title5','created':'19'}];

var endResult = mergeSort(a,b);
document.getElementsByTagName('p')[0].innerHTML = JSON.stringify(endResult);
&lt;p&gt;&lt;/p&gt;

【讨论】:

    【解决方案2】:

    您可以采用嵌套循环并在 concat 之后对数组进行排序。

    function sort(array) {
        var sorted = [],
            i = array.length,
            j;
    
        while (i--) {
            for (j = 0; j < sorted.length; j++) {
                if (array[i].created < sorted[j].created) {
                    break;
                }
            }
            sorted.splice(j, 0, array[i]);
        }
        return sorted;
    }
    
    var a = [{ title: 'title1', created: '18' }, { title: 'title2', created: '16' }, { title: 'title3', created: '20' }],
        b = [{ title: 'title4', created: '17' }, { title: 'title5', created: '19'}],
        result = sort(a.concat(b));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案3】:

      这似乎运作良好,虽然我无法说出它的速度。

        const arr1 = [111,2,300,50,6,71,9];
        const arr2 = [122,8,40,29,611,74,1];
        // Combines the two arrays into one
        const unsorted = arr1.concat(arr2);
        const sorted = [];
      
        for(i = 0; i < unsorted.length; i++){
          // Adds all elements from the unsorted array to the destination (sorted) array
          insert(unsorted[i], sorted);
        }
        console.log(sorted);
      
        function insert(item, arr){
          // Adds the first item automatically
          if(arr.length == 0){
            arr.push(item); 
            return; 
          }
          for(let i = 0; i < arr.length; i++){
            if(i + 1 == arr.length){
              // Adds the item at the end of the array because it's so big 
              arr.push(item);
              break;
            }
      
            else if(item < arr[i]){
              // Adds the item at the appropriate position in the sorted array
              arr.splice(i, 0, item);
              break;
            }
          }
        }
      

      【讨论】:

        【解决方案4】:

        使用内置的sortconcat 函数很容易做到这一点。

        自定义逻辑可以提供给比较器函数。很难想象任何必需的排序都不能以这种方式完成。

        // `comparator` contains your custom business logic.  Return a negative number if `a`
        // is smaller than `b`, a positive one if it's larger, and 0 if they're equal.
        
        const mergeAndSort = (comparator) => (a, b) => a.concat(b).sort(comparator)
        
        const myComparator = (a, b) => {
          return Number(a.created) - Number(b.created)  // or just `a.created - `b.created`
        }
        
        const a = [{ title: 'title1', created: '18' }, { title: 'title2', created: '16' }, { title: 'title3', created: '20' }],
              b = [{ title: 'title4', created: '17' }, { title: 'title5', created: '19'}]
        
        console.log(mergeAndSort(myComparator)(a, b))

        这是学习如何编写排序算法的尝试吗?如果没有,那么我会采用这样的方法。

        【讨论】: