javascript在特定情况下具有重复元素的过滤器数组

时间:2019-03-02 11:37:35

标签: javascript arrays string function object

我有一个名字数组,每个名字都有重复。

let arr = ['John', 'Jack', 'John', 'Jack', 'Jack', 'June', 'June'];

我想用一些重复的元素创建一个新的数组,并指定它们发生的实例。

例如,我可能希望数组仅包含第二次出现的John,Jack和June。该数组将如下所示:

'John', 'Jack', 'June'

为此,我声明了一个对象ni并循环访问arr以向与每个名称相对应的对象添加属性。该属性将保存包含名称在其上出现的每个索引的数组的值。

let ni  = {};

for(let i = 0; i < arr.length; i++) {
  let name = arr[i];
  if(nc.hasOwnProperty(name)) {
    ni[name].push(i);
  } else {
    ni[name] = [i];
  }
}

console.log(ni);
// > Object { John: Array [0, 2], Jack: Array [1, 3, 4], June: Array [5, 6] }

在我的Array.filter函数中,我检查元素的索引是否等于对应于相同名称的object属性的索引1。

let newArr = arr.filter(function(name) {
  if(ni.hasOwnProperty(name)) {
    return arr.indexOf(name) === ni[name][1];
  }
});

这应该将John的{​​{1}},index 2的{​​{1}}和Jack的{​​{1}}返回到新数组。

但是,这没有用。将index 3登录到控制台将输出与原始阵列完全相同的阵列。

June

3 个答案:

答案 0 :(得分:2)

您可以使用一些简单的数组逻辑,如下所示:

let newArr = arr.filter((e, i) => i == ni[e][1]);

答案 1 :(得分:2)

您可以使用reduce来计算每个名称的出现次数。如果名称的计数为2,则推到另一个数组。这样,您不必运行嵌套数组方法:

const array = ['Jane', 'John', 'Jack', 'John', 'Jack', 'Jack', 'June', 'June'];
const filtered = [];
const count = array.reduce((a, name) => {
  a[name] = a[name] + 1 || 1;
  if(a[name] === 2)
    filtered.push(name)
  
  return a;
}, {});

console.log(filtered)

或者获取count> 1的计数器键

const array = ['Jane', 'John', 'Jack', 'John', 'Jack', 'Jack', 'June', 'June'],
      count = array.reduce((a, n) => (a[n] = a[n] + 1 || 1, a), {}),
      filtered = Object.keys(count).filter(n => count[n] > 1);
      
console.log(filtered)

答案 2 :(得分:1)

我正在创建一个对象而不是数组,因为它似乎更适合从名称映射到第二个外观的索引。它的工作方式如下:indexOf返回数组中元素第一次出现的索引,因此如果indexOf不等于当前索引,那么它是第二次出现或以后出现的索引,那么我检查名称是否还没有出现在返回对象中,所以我知道它不是第3次或以后发生。

let arr = ['John', 'Jack', 'John', 'Jack', 'Jack', 'June', 'June'];
let newObj = arr.reduce(function(acc, cur, idx) {
  if (arr.indexOf(cur)!==idx && !acc[cur]) { acc[cur] = idx; }
	return acc;
}, {});
console.log(newObj);