【问题标题】:Javascript - find out first element appears in sorted array as well as in another unsorted collectionJavascript - 找出第一个元素出现在排序数组以及另一个未排序集合中
【发布时间】:2020-04-30 23:21:31
【问题描述】:

我有一个未排序的数组和另一个排序的数组,比如

const unSortedArray = [54, 23, 55, 76, 9, 11];
const sortedArray= [1, 2, 3, 4, ...., 100]

我怎样才能知道first element 出现在我的sortedArray 中,这也应该是我的unSortedArray 中存在的一个元素?在上面的示例中,应该返回 9,因为 9 存在于 unSortedArray 中,并且它位于 sortedArray 中的其他元素之前

注意,我在上面的示例中使用了 1、2、3、4,但我的实际示例不是数字,而是 GUID,假设我们 不能在 @ 上应用排序方法987654325@ 然后选择第一个元素。

我考虑过合并两个数组,但是如何在不破坏 sortedArray 排序的同时合并两个数组?

这里有一些例子

1) 输出应该是 1,因为偶数元素 1、2、9 和 10 都存在于两个数组中,1 比 sortedArray 中的 2、9、10 优先顺序

const unSortedArray = [54, 23, 55, 76, 9, 10, 2, 1]; 
const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 

2) 输出应该是 9,因为即使元素 9 和 10 都存在于两个数组中,9 在 sortedArray 中的顺序比 10 优先

const unSortedArray = [54, 23, 55, 76, 10, 9]; 
const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 

3) 输出应该是 '' 因为 unSortedArray 中没有元素出现在 sorted Array 中

const unSortedArray = [54, 23, 55, 76, 11]; 
const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 

【问题讨论】:

    标签: javascript algorithm sorting filter


    【解决方案1】:

    使用 for 循环的一种快速而肮脏的方法:

    const unSortedArray = [54, 23, 55, 76, 9, 11];
    const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    let firstVal;
    for (i = 0; i < sortedArray.length; i++) {
      if (unSortedArray.includes(sortedArray[i])) {
        firstVal = sortedArray[i];
        break;
      }
    }
    
    console.log(firstVal);

    【讨论】:

    • 您可以使用 reduce() 使其成为单行:console.log(sortedArray.reduce((acc,val) =&gt; unSortedArray.includes(val) ? val : acc));
    • “累加器”的缩写。它是包含reduce() 内函数返回值的变量。见:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • 嗨@Ed Lucas,sortedArray.reduce((acc,val) =&gt; unSortedArray.includes(val) ? val : acc) 似乎有一个错误,如果 unSortedArray 不包含排序数组中的任何元素,那么它将以某种方式返回 sortedArray 中的第一个元素,有没有办法返回为空还是未定义?
    • 可以使用reduce()的第二个参数为累加器设置一个默认值:sortedArray.reduce((acc,val) =&gt; unSortedArray.includes(val) ? val : acc, null)
    • 如果在下面的示例中,这将不起作用 ``` const unSortedArray = [54, 23, 55, 76, 9, 11, 1, 2];常量 sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const first = sortedArray.reduce((acc,val) => unSortedArray.includes(val) ? val : acc, '');控制台.log(第一); ``` 它总是输出 9 而不是 1...
    【解决方案2】:

    您可以从unSortedArray 创建一个Set,并在sortedArray.find() 的谓词中使用set.has()

    const unSortedArray = [54, 23, 55, 76, 9, 11];
    const sortedArray= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    const setHasValue = set => value => set.has(value);
    const firstElement = sortedArray.find(setHasValue(new Set(unSortedArray)));
    
    console.log(firstElement);

    【讨论】:

    • 我的两个数组值已经不同了,是不是因为我们要使用 Set.has 需要在这里声明一个 Set?
    • @KevDing 这不是关于唯一性,而是关于 set.has() O(1) 与 array.includes() O(n) 的时间复杂度
    • 感谢您的考虑!
    【解决方案3】:

    为未排序的数组项构建一个查找表是个好主意。比如

    { 54: true
    , 23: true
    , 55: true
    .
    .
      11: true
    }
    

    这将是一个 O(k) 任务,其中k 是未排序数组的元素数。然后find 排序数组中返回true 的第一项。这应该是一个 O(n) 任务,其中n 是排序数组的元素数。产生线性时间解。

    应该这样做。

    function getFirst(usa,sa){
      var h = usa.reduce((r,n) => (r[n] = true, r), {});
      return sa.find(n => h[n]);
    }
    
    var r = getFirst([54,23,55,76,9,11], Array.from({length:100}, (_,i) => i+1));
    console.log(r);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-23
      • 2020-09-12
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      相关资源
      最近更新 更多