首页 > 解决方案 > 合并具有特定条件的数组

问题描述

我遇到了 javascript 的挑战。我有一个称为数组的数组。我正在尝试将用户 A 与用户 B 与 C 进行比较。用户 A、用户 B 和用户 C 是动态值,并且会不断变化。

如果用户 A 和用户 B 和用户 C 的日期和时间相等,则显示输出。例如,如果

  var arrays = ['7/10/2021', 'User A', 'Thu', 'even', '09:00 - 09:20'],
  ['7/10/2021', 'User B', 'Thu', 'even', '09:00 - 09:20'],
  ['7/10/2021', 'User C', 'Thu', 'even', '09:00 - 09:20'],
  ['7/10/2021', 'User C', 'Thu', 'even', '10:00 - 10:20'],

那么它应该只显示这个。

['7/10/2021', 'Thu', 'even', '09:00 - 09:20'],

我目前的代码是:

var arrays = ['7/10/2021', 'User A', 'Thu', 'even', '09:00 - 09:20'],
  ['7/10/2021', 'User B', 'Thu', 'even', '09:00 - 09:20'],
  ['7/10/2021', 'User C', 'Thu', 'even', '09:00 - 09:20'],
  ['7/10/2021', 'User C', 'Thu', 'even', '10:00 - 10:20']
], result = [];
var frequency = arrays .reduce(function(seen, currentItem) {
if (currentItem in seen) {
    seen[currentItem] = seen[currentItem] + 1;
} else {
    seen[currentItem] = 1;
}
return seen;
},  {});

for (var key in frequency) {
if (frequency[key] > 1) {
    result.push(key.split(",").map(function(currentItem) {
        return parseInt(currentItem);
     }));
 }
 }

 console.log(result);

 My result: []

我试过这个

var arrays = [
['7/10/2021', 'User A', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User A', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User C', 'Thu', 'even', '09:00 - 09:20'],
['7/10/2021', 'User C', 'Thu', 'even', '10:00 - 10:20']];

var myArrayFiltered = arrays.filter(function(item, pos) {
  return arrays.indexOf(item) == pos;
});

console.log(myArrayFiltered)

但它显示所有不是我想要的用户。

标签: javascript

解决方案


我记得几个小时前的这个问题。正如你所说,你的数据结构是固定的(即每行有5个元素,顺序相同)。

下面的这个快速破解应该可以满足您的需求。它可能不是最优雅的解决方案(尤其是数组的字符串化和解析),但它完成了工作。

解释见代码中的注释

//this is the index that will be excluded for comparisons
let userindex = 1;
let data = [
  ['date1', 'user a', 'day 1', 'even', 'time 1'],
  ['date1', 'user a', 'day 1', 'even', 'time 2'],
  ['date1', 'user a', 'day 2', 'even', 'time 1'],
  ['date1', 'user b', 'day 1', 'even', 'time 1'],
  ['date2', 'user b', 'day 1', 'even', 'time 2'],
  ['date1', 'user b', 'day 2', 'even', 'time 1'],
  ['date1', 'user c', 'day 1', 'even', 'time 1'],
  ['date2', 'user c', 'day 1', 'even', 'time 2'],
  ['date1', 'user c', 'day 2', 'even', 'time 3'],
]

//get the number of distinct users
let users = data.map(row => row[userindex]) //get the user
              .filter((u, i, arr) => arr.indexOf(u) === i) //only get first occurence of each username
              .length;  //count the elements in the resulting array

//group by different combinations and get users for each distinct combination
let groups = data.reduce((a, row) => {
  //remove username from row and stringify the resulting array to use as key in object
  let key = JSON.stringify(row.filter((_, i) => i != userindex));
  //check if the current combination is already contained in the object, and add if not
  if (!a[key]) a[key] = [];
  //if the current user isn't contained for the combination add it
  if (!a[key].includes(row[userindex])) a[key].push(row[userindex]);
  return a;
}, {})

//get only elements which contain all users
let valids = Object.entries(groups) //get an array of [[key, value]] for the group object
  .filter(e => e[1].length == users)  //filter it for elements which contain all users
  .map(e => JSON.parse(e[0])); //parse the key back to an array

console.log(valids)


推荐阅读