我想基于一个公共属性找到多个对象数组的公共元素。另外,如果一个元素出现不止一次,我希望结果数组反映它在所有数组中出现的次数。

我尝试了以下方法:



var arr = [
    [
        { name: 'kiwi', value: 12 },
        { name: 'apple', value: 5 },
        { name: 'apple', value: 12 },
        { name: 'pizza', value: 33 },
        { name: 'pizza', value: 24 },
        { name: 'fish', value: 5 },
        { name: 'milk', value: 5 },
        { name: 'banana', value: 7 },
        { name: 'orange', value: 11 },
    ],
    [
        { name: 'taco', value: 23 },
        { name: 'pizza', value: 78 },
        { name: 'apple', value: 12 },
        { name: 'pizza', value: 33 },
        { name: 'pizza', value: 24 },
        { name: 'fish', value: 5 },
        { name: 'pie', value: 1 },
        { name: 'cake', value: 3 },
        { name: 'banana', value: 7 },
        { name: 'beef', value: 123 },
        { name: 'lime', value: 72 },
        { name: 'pizza', value: 34 },
    ],
    [
        { name: 'apple', value: 12 },
        { name: 'pizza', value: 33 },
        { name: 'pizza', value: 24 },
        { name: 'pizza', value: 23 },
        { name: 'fish', value: 5 },
        { name: 'banana', value: 7 },
        { name: 'banana', value: 77 },
    ]
];

function findArraysWithCommonName(arr) {
  let arrays = [...arr];
  var result = arrays.shift().reduce(function(res, v) {
    if (arrays.every(function(a) {
        return (a.filter(function(e) {
          return e.name === v.name
        }).length > 0);
      })) res.push(v);
    return res;
  }, []);
  return result;
}

console.log(findArraysWithCommonName(arr))





我得到的结果是:

[
{name: "apple", value: 5},
{name: "apple", value: 12},
{name: "pizza", value: 33},
{name: "pizza", value: 24},
{name: "fish", value: 5},
{name: "banana", value: 7}
]



我希望输出为:

[
{name: "apple", value: 12},
{name: "pizza", value: 33},
{name: "pizza", value: 24},
{name: "fish", value: 5},
{name: "banana", value: 7}
]


要么

[
{name: "apple", value: 5},
{name: "pizza", value: 33},
{name: "pizza", value: 24},
{name: "fish", value: 5},
{name: "banana", value: 7}
]

最佳答案

一种方法是建立一个将对象与其数组中“计数”相关联的映射(即对象在arr中占的次数)。

这可以通过.reduce()完成,在该过程中,您通过JSON.stringify(obj)将每个对象序列化为一个字符串-该字符串是对应对象形状和状态的唯一编码,用作key来标识此形式的对象映射。 key用于为arr中遇到的每个对象查询和更新映射的“计数”值。

构建映射后,请按“计数”值大于1的那些过滤映射项。

最后,对于任何过滤的条目,通过.map()反序列化这些条目的相应键,以获得对象数组,该对象数组在原始arr中占据的空间大于一个。

这种方法可以实现为:



var arr=[[{name:'kiwi',value:12},{name:'apple',value:5},{name:'apple',value:12},{name:'pizza',value:33},{name:'pizza',value:24},{name:'fish',value:5},{name:'milk',value:5},{name:'banana',value:7},{name:'orange',value:11}],[{name:'taco',value:23},{name:'pizza',value:78},{name:'apple',value:12},{name:'pizza',value:33},{name:'pizza',value:24},{name:'fish',value:5},{name:'pie',value:1},{name:'cake',value:3},{name:'banana',value:7},{name:'beef',value:123},{name:'lime',value:72},{name:'pizza',value:34}],[{name:'apple',value:12},{name:'pizza',value:33},{name:'pizza',value:24},{name:'pizza',value:23},{name:'fish',value:5},{name:'banana',value:7},{name:'banana',value:77}]];


/* Flatten array heirachy */
const flatArr = arr.flat();

/* Obtain a count mapping for each object's occourance in flatArr */
const mapObjectToCount = flatArr.reduce((map, item) => {

  const key = JSON.stringify(item);
  const count = (map[key] ? map[key] : 0) + 1;

  return { ...map, [ key ] : count };
}, {})

/* Get key/value pair of the prior mapping, filter the objects by
those that occour more that one time, and obtain the original object
by parsing the key */
const result = Object.entries(mapObjectToCount)
.filter(([json, count]) => count > 1)
.map(([json]) => JSON.parse(json));

console.log(result)

关于javascript - 基于属性的多个数组的交集,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57650251/

10-13 00:03
查看更多