我有一个名字数组,每个名字都有重复。
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
答案 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);