簡體   English   中英

使用 lodash 比較鋸齒狀數組(項目存在無序)

[英]Using lodash to compare jagged arrays (items existence without order)

我知道我可以使用循環來做到這一點,但我試圖找到一種優雅的方式來做到這一點:

我有兩個鋸齒狀數組(數組數組):

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];

我想用lodash來確認上面兩個鋸齒狀的數組是一樣的。 “相同”是指array1中沒有不包含在array2 請注意,鋸齒狀數組中的項目實際上是數組。 所以我想在內部數組之間進行比較。

在檢查這些項目之間的相等性方面:

['a', 'b'] == ['b', 'a'] 

或者

['a', 'b'] == ['a', 'b'] 

兩者都有效,因為字母總是按順序排列的。


更新:最初的問題是在談論“數組”(而不是鋸齒狀數組),多年來許多人討論(並添加了答案)關於比較簡單的一維數組(沒有注意到問題中提供的示例實際上並不類似於他們期望的簡單一維數組)。

如果對外部數組進行排序,則可以使用_.isEqual()因為內部數組已經排序。

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
_.isEqual(array1.sort(), array2.sort()); //true

請注意, .sort()將改變數組。 如果這對您來說是個問題,請先使用(例如) .slice()或展開運算符 ( ... ) 進行復制。

或者,按照 Daniel Budick 在以下評論中的建議進行操作:

_.isEqual(_.sortBy(array1), _.sortBy(array2))

Lodash 的sortBy()不會改變數組。

您可以為此使用 lodashs xor

doArraysContainSameElements = _.xor(arr1, arr2).length === 0

如果您認為數組 [1, 1] 與數組 [1] 不同,那么您可以像這樣提高性能:

doArraysContainSameElements = arr1.length === arr2.length === 0 && _.xor(arr1, arr2).length === 0

“相同”是指 array1 中沒有不包含在 array2 中的項目。

您可以為此使用 flatten() 和 difference() ,如果您不關心array2是否有不在array1中的項目,這會很好用。 聽起來您是在問array1 是 array2 的子集嗎?

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];

function isSubset(source, target) {
    return !_.difference(_.flatten(source), _.flatten(target)).length;
}

isSubset(array1, array2); // → true
array1.push('d');
isSubset(array1, array2); // → false
isSubset(array2, array1); // → true

這里已經有了答案,但這是我的純 JS 實現。 我不確定它是否是最佳的,但它肯定是透明的、可讀的和簡單的。

// Does array a contain elements of array b?
const union = new Set([...a, ...b]);
const contains = (a, b) => union.size === a.length && union.size === b.length;
// Since order is not important, just data validity.
const isEqualSet = (a, b) => union.contains(a, b) || union.contains(b, a)

contains()的基本原理是,如果a確實包含b所有元素,那么將它們放入同一個集合中不會改變大小。

例如,如果const a = [1,2,3,4]const b = [1,2] ,則new Set([...a, ...b]) === {1,2,3,4} 正如你所看到的,所產生的一組具有相同的元件作為a

從那里,為了使它更簡潔,我們可以將其歸結為以下內容:

const isEqualSet = (a: string[], b: sting[]): boolean => {
  const union = new Set([...a, ...b])
  return union.size === a.length && union.size === b.length;
}

編輯:這不適用於 obj[{a: true}, true, 3] 但可能會比較數組內容,只要它們是原始元素。 使用不同順序的相同值對字符串兩個數組進行修復和測試的方法。 不適用於對象類型。 我建議制作一個通用助手,它根據需要比較的類型調用助手函數。 試試_.isEqual(a. b); 來自非常棒的 lodash 庫。

PURE JS(當數組和子數組具有超過 2 個任意順序的元素時也適用)。 如果字符串包含,使用字符串中未使用的join('-')參數字符(可以是 utf)

array1.map(x=>x.sort()).sort().join() === array2.map(x=>x.sort()).sort().join()

 var array1 = [['a', 'b'], ['b', 'c']]; var array2 = [['b', 'c'], ['b', 'a']]; var r = array1.map(x=>x.sort()).sort().join() === array2.map(x=>x.sort()).sort().join(); console.log(r);

我絕對覺得發布這個解決方案很不干凈,但是:

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
_.isMatch([array1], [array2]) && _.isMatch([array2], [array1]) // true

array1 = [['b', 'a'], ['c', 'b']];
array2 = [['b', 'c'], ['a', 'b']];
_.isMatch([array1], [array2]) && _.isMatch([array2], [array1]) // also true

請注意,您必須array1array2包裝到一個容器(數組、對象)中才能使其工作? 為什么? 這可能有一個非常愚蠢的原因。

import { differenceBy } from 'lodash'

export default function (arr1, arr2) {
    return !differenceBy(arr1, arr2).length && arr1.length === arr2.length
}

如果沒有不同的字符並且數組長度相同,則使它們相同。

編輯:我錯過了這個問題的多維方面,所以我把它留在這里以防它幫助人們比較一維數組

這是一個老問題,但我在使用.sort()sortBy()的速度方面遇到了問題,所以我改用了這個:

function arraysContainSameStrings(array1: string[], array2: string[]): boolean {
  return (
    array1.length === array2.length &&
    array1.every((str) => array2.includes(str)) &&
    array2.every((str) => array1.includes(str))
  )
}

它旨在快速失敗,並且對我而言效果很好。

我們可以使用_.difference函數來查看是否有任何差異。

function isSame(arrayOne, arrayTwo) {
   var a = _.uniq(arrayOne),
   b = _.uniq(arrayTwo);
   return a.length === b.length && 
          _.isEmpty(_.difference(b.sort(), a.sort()));
}

// examples
console.log(isSame([1, 2, 3], [1, 2, 3])); // true
console.log(isSame([1, 2, 4], [1, 2, 3])); // false
console.log(isSame([1, 2], [2, 3, 1])); // false
console.log(isSame([2, 3, 1], [1, 2])); // false

// Test cases pointed by Mariano Desanze, Thanks.
console.log(isSame([1, 2, 3], [1, 2, 2])); // false
console.log(isSame([1, 2, 2], [1, 2, 2])); // true
console.log(isSame([1, 2, 2], [1, 2, 3])); // false

我希望這能幫到您。

StackBlitz添加示例鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM