返回数组中奇数的索引

时间:2019-05-14 15:52:52

标签: javascript

我需要在单词(字符串)数组中返回奇数单词的索引。

例如...

['junper', 'jumper'] should return 0 
['Jumper'] should return 0 
['coast', 'coast', 'coal', 'coast'] should return 2
['sofa', 'sofa', 'sofa', 'soft'] should return 3

我已经有一个可行的解决方案,但我的目标是使它更清洁。

我一直在思考返回仅出现一次的单词索引的最佳方法是什么...

这是我前面提到的有效解决方案:

function findWrongWord(householditems) {
    if (householditems.length < 3) return 0;

    function findOccurencesLength (array, toEqual) {
        return array.filter(x => x === toEqual).length
    }

    let copyOfInitialArray = [...householditems];
    let [, mostOccuredItem = ''] = copyOfInitialArray.sort((a, b) => 
        findOccurencesLength(copyOfInitialArray, a) - 
        findOccurencesLength(copyOfInitialArray, b));

    return householditems.findIndex(x => x === 
        mostOccuredItem.split('').reverse().join(''));
}

5 个答案:

答案 0 :(得分:2)

您可以比较indexOflastIndexOf来检查元素是否重复。

const nonRepeated = arr => arr.findIndex(x => arr.indexOf(x) === arr.lastIndexOf(x))

console.log(nonRepeated(['junper', 'jumper']))
console.log(nonRepeated(['Jumper'] ))
console.log(nonRepeated(['coast', 'coast', 'coal', 'coast']))
console.log(nonRepeated(['sofa', 'sofa', 'sofa', 'soft']))

另一种方法是使用对象获取所有元素的计数,然后返回计数为1的元素中的第一个。

const nonRepeated = arr => {
  let countObj = arr.reduce((ac,a,i) => {
    if(!ac[a]) ac[a] = {count:0,index:i};
    ac[a].count++;
    return ac;
  },{})
  return Object.values(countObj).find(x => x.count === 1).index;

}
console.log(nonRepeated(['junper', 'jumper']))
console.log(nonRepeated(['Jumper'] ))
console.log(nonRepeated(['coast', 'coast', 'coal', 'coast']))
console.log(nonRepeated(['sofa', 'sofa', 'sofa', 'soft']))

答案 1 :(得分:1)

如果您想找到一个仅在阵列上出现一次的word,也许可以使用Array.findIndex()Array.filter()的组合,如下所示:

const tests = [
  ['junper', 'jumper'],
  ['Jumper'],
  ['coast', 'coast', 'coal', 'coast'],
  ['sofa', 'sofa', 'sofa', 'soft']
];

const getIndex = (arr) =>
{
    return arr.findIndex(word => arr.filter(x => x === word).length === 1);
}

tests.forEach(
    test => console.log(`${test} -> ${getIndex(test)}`)
);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

另一种方法是首先使用Array.reduce()来生成具有每个单词的频率的Map(),然后找到具有频率word的第一个1

const tests = [
  ['junper', 'jumper'],
  ['Jumper'],
  ['coast', 'coast', 'coal', 'coast'],
  ['sofa', 'sofa', 'sofa', 'soft']
];

const getIndex = (arr) =>
{
    let freq = arr.reduce((acc, word) =>
    {        
        acc.set(word, acc.has(word) ? acc.get(word) + 1 : 1);
        return acc;
    }, new Map())

    return arr.findIndex(word => freq.get(word) === 1);
}

tests.forEach(
    test => console.log(`${test} -> ${getIndex(test)}`)
);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

答案 2 :(得分:0)

尝试(其中h = {})

a.indexOf(a.map(e=>(h[e]=++h[e]|0,e)).find(w=>!h[w]));

let test = [
  ['junper', 'jumper'],
  ['Jumper'],
  ['coast', 'coast', 'coal', 'coast'],
  ['sofa', 'sofa', 'sofa', 'soft'],
];

function findWrongWord(a) {
  let h={};
  return a.indexOf(a.map(w=>(h[w]=++h[w]|0,w)).find(w=>!h[w]));
}

test.map(t=> console.log(JSON.stringify(t),findWrongWord(t)));

答案 3 :(得分:0)

一种想法是使用地图维护索引位置和计数列表, 进行下一步排序,然后取消移动第一个项目。

下面是一个有效的代码段。

const oddOne = arr => 
  arr.map((m,i,a) => (
    {i, c: a.filter(f => f === m).length})
  ).sort((a,b) => a.c - b.c).shift().i;
  
const tests = [
  ['junper', 'jumper'],
  ['Jumper'],
  ['coast', 'coast', 'coal', 'coast'],
  ['sofa', 'sofa', 'sofa', 'soft']
];

for (const test of tests) {
  console.log(JSON.stringify(test), "=", oddOne(test));
}

答案 4 :(得分:0)

首先,我要做一个假设,您已经知道数组中只有一个“奇数”字。我的javascript不好,所以我会用语言写下来。它不是最漂亮的解决方案,但却是合乎逻辑的

  1. 创建一个整数数组,该数组的长度与要测试的数组相同。该数组中的每个元素将代表您正在测试的数组中相应单词出现的次数。

    Array appearances = new Array(testArray.length);
    

    //将所有元素实例化为零

  2. 对于测试数组中的每个元素,测试其是否等于位置1、2、3,...,最后一个位置的元素,并使其在相等的位置处变小

    for(int i = 0; i

  3. 现在我们在外观数组中找到1,我认为array.find()是这样,它的索引也将是与其他单词不相似的单词的索引。