【问题标题】:JS - nested for loops - compare 2 arrays by key, return 4 new arrays, matches & unmatches from eachJS - 嵌套 for 循环 - 按键比较 2 个数组,返回 4 个新数组,每个数组匹配和不匹配
【发布时间】:2022-01-26 08:15:10
【问题描述】:

为这个问题做了一个演示 -

数组 -

const arr1 = [
  {
    key: "daniel|21",
    name: "daniel",
    age: 21,
    city: "NYC"
  },
  {
    key: "kosta|28",
    name: "kosta",
    age: 28,
    city: "NYC"
  }
];

const arr2 = [
  {
    key: "daniel|21",
    name: "daniel",
    age: 21,
    city: "TLV"
  },
  {
    key: "simon|24",
    name: "simon",
    age: 24,
    city: "NYC"
  },
  {
    key: "david|22",
    name: "david",
    age: 22,
    city: "NYC"
  }
];

用于赋值的空数组 -

let arr1Match = [];
let arr1Unmatch = [];

let arr2Match = [];
let arr2Unmatch = [];

For循环-

for (let i = 0; i < arr1.length; i++) {
for (let j = 0; j < arr2.length; j++) {
    const arr1Key = arr1[i].key;
    const arr2Key = arr2[j].key;

    if (arr1Key === arr2Key) {
        arr1Match.push(arr1[i])
        arr2Match.push(arr2[i])
    } else {
        arr1Unmatch.push(arr1[i])
        arr2Unmatch.push(arr2[i])
    }
}

}

我在输出什么 -

console.log(arr1Match);
console.log(arr1Unmatch);

console.log(arr2Match);
console.log(arr2Unmatch);

输出 -

arr1Match:[{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "NYC" }]

arr1Unmatch:[{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "NYC" }, { "key": "daniel|21", "name": "daniel", "age": 21, "city": "NYC" }, { "key": "kosta|28", "name": "kosta", "age": 28, "city": "NYC" }, { "key": "kosta|28", "name": "kosta", "age": 28, "city": "NYC" }, { "key": "kosta|28", "name": "kosta", "age": 28, "city": "NYC" }]

arr2Match: [{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "TLV" }]

arr2Unmatch:[{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "TLV" }, { "key": "daniel|21", "name": "daniel", "age": 21, "city": "TLV" }, { "key": "simon|24", "name": "simon", "age": 24, "city": "NYC" }, { "key": "simon|24", "name": "simon", "age": 24, "city": "NYC" }, { "key": "simon|24", "name": "simon", "age": 24, "city": "NYC" }]

想要的输出 -

arr1Match:[{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "NYC" }]

arr1Unmatch:[{ "key": "kosta|28", "name": "kosta", "age": 28, "city": "NYC" }]

arr2Match:[{ "key": "daniel|21", "name": "daniel", "age": 21, "city": "TLV" }]

arr2Unmatch:[{ "key": "simon|24", "name": "simon", "age": 24, "city": "NYC" }, { "key": "david|22", "name": "david", "age": 22, "city": "NYC" }]

我需要循环遍历数组中的所有值并返回每个值的所有匹配项和不匹配项。 如果有匹配项,我需要将属性从 arr2 分配到 arr1

【问题讨论】:

  • @ikhvjs 我不好我会编辑我需要嵌套的 for 循环
  • @pilchard 我大错特错,编辑了我需要为每个 arr1 元素在 arr2 上运行的问题

标签: javascript arrays loops for-loop


【解决方案1】:

我不太确定我理解你的问题,这是你想要的结果吗?

const arr1 = [{
    key: "daniel|21",
    name: "daniel",
    age: 21,
    city: "NYC"
  },
  {
    key: "kosta|28",
    name: "kosta",
    age: 28,
    city: "NYC"
  }
];

const arr2 = [{
    key: "daniel|21",
    name: "daniel",
    age: 21,
    city: "TLV"
  },
  {
    key: "simon|24",
    name: "simon",
    age: 24,
    city: "NYC"
  },
  {
    key: "david|22",
    name: "david",
    age: 22,
    city: "NYC"
  }
];

const arr1Keys = arr1.map(a => a.key);
const arr2Keys = arr2.map(a => a.key);
const keys = [...arr1Keys, ...arr2Keys];
const repeat = keys.filter((o, i) => keys.indexOf(o) !== i);
const unique = [...new Set(keys)].filter(o => !repeat.includes(o));

const arr1Match = arr1.filter(a => repeat.includes(a.key));
const arr1Unmatch = arr1.filter(a => unique.includes(a.key));
const arr2Match = arr2.filter(a => repeat.includes(a.key));
const arr2Unmatch = arr2.filter(a => unique.includes(a.key));
const arr1Match2 = arr1Match.map(a1 => {
  let obj = arr2Match.find(a2 => a2.key == a1.key);
  return {...obj, city: obj.city}
});
const arr1Match3 = arr1Match.map(a1 => arr2Match.find(a2 => a2.key == a1.key));

console.log('arr1Match before', JSON.stringify(arr1Match));
console.log('arr1Match overwrite city', JSON.stringify(arr1Match2));
console.log('arr1Match overwrite all', JSON.stringify(arr1Match3));
console.log('arr1Unmatch', JSON.stringify(arr1Unmatch));
console.log('arr2Match', JSON.stringify(arr2Match));
console.log('arr2Unmatch', JSON.stringify(arr2Unmatch));

【讨论】:

  • 我不能用你的方式。当有匹配时,我需要将属性从 arr2 分配到 arr1
  • @heyheyhey 匹配时从 arr2 到 arr1 的属性是什么,你能更具体一点吗?
  • 如果:{ key: "daniel|21", name: "daniel", age: 21, city: "NYC" } 等于:{ key: "daniel|21", name: "daniel", age: 21, city: "TLV" } 我需要将属性从arr2 分配给arr1 - 例如,假设@987654327 中的city @ 在输出中应该是 TLV。在示例中,我正在更改现有值,但这样您可以尽可能好地理解问题
  • @heyheyhey 哦所以你的意思是匹配完成后,需要将arr1中的对象属性替换为arr2中相同key的对象属性吗?
  • @heyheyhey 嗨我调整了代码,你可以再看一遍,里面有替换其中一个属性和替换所有属性的代码
【解决方案2】:

找到常见对象并更新它们的方法。

const
    update = (a, b) => {
        const
            fn = o => o.key,
            references = Object.fromEntries(a.map(o => [fn(o), o]));

        b.forEach(o => {
            const target = references[fn(o)];
            if (target) Object.assign(target, o);
        });
    }
    array1 = [{ key: "daniel|21", name: "daniel", age: 21, city: "NYC" }, { key: "kosta|28", name: "kosta", age: 28, city: "NYC" }],
    array2 = [{ key: "daniel|21", name: "daniel", age: 21, city: "TLV" }, { key: "simon|24", name: "simon", age: 24, city: "NYC" }, { key: "david|22", name: "david", age: 22, city: "NYC" }];

update(array1, array2);

console.log(array1); // inclusive the one with updates!
.as-console-wrapper { max-height: 100% !important; top: 0; }

您可以获取公共键并获取每个数组的分区。

const
    match = (a, b, fn) => {
        const 
            getCommon = (a, b) => {
                const c = {};
                a.forEach(o => c[fn(o)] = false);
                b.forEach(o => c[fn(o)] = fn(o) in c);
                return c;
            };
            common = getCommon(a, b, fn),
            getParts = (a, c) => a.reduce((r, o) => (r[+!common[fn(o)]].push(o), r), [[], []]);
            
        return [
            getParts(a, common),
            getParts(b, common)
        ];
    }
    array1 = [{ key: "daniel|21", name: "daniel", age: 21, city: "NYC" }, { key: "kosta|28", name: "kosta", age: 28, city: "NYC" }],
    array2 = [{ key: "daniel|21", name: "daniel", age: 21, city: "TLV" }, { key: "simon|24", name: "simon", age: 24, city: "NYC" }, { key: "david|22", name: "david", age: 22, city: "NYC" }],
    [
        [arr1Match, arr1Unmatch],
        [arr2Match, arr2Unmatch]
    ] = match(array1, array2, o => o.key);

console.log(arr1Match);
console.log(arr1Unmatch);

console.log(arr2Match);
console.log(arr2Unmatch);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我需要获取不同数组中的匹配项和不匹配项
  • 抱歉,我现在编辑了问题
  • @heyheyhey,怎么了?
  • 我需要从arr2arr1 分配一个属性,如果有一个匹配的例子让我们说 - 如果:{ key: "daniel|21", name: "daniel", age: 21, city: "NYC"} 等于:{ key: "daniel|21", name: "daniel", age: 21, city: "TLV"} 我需要将属性从 arr2 分配给 arr1 - 例如,假设 arr1 中的城市在输出中应该是 TLV。在示例中,我正在更改现有值,但这样您可以尽可能好地理解问题
  • 它的结果是什么?什么属性?
猜你喜欢
  • 1970-01-01
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 2020-01-02
  • 2015-04-15
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多