javascript 打印包含给定单词的所有字符的列表项

mgdq6dx1  于 2023-04-04  发布在  Java
关注(0)|答案(3)|浏览(189)

输出只能是:rabbit和bibe但是我弄错了列表中的所有内容都是打印的,因为最后一个索引也有'b',我怎么能打印只包含'bib'的指定元素呢

let str = 'bib'
let list = ['rabbit','bibe','bundle']
for(let i = 0; i < list.length;i++){
    for(let j = 0; j < list[i].length; j++){
        let foundIndex = str.indexOf(list[i][j])>-1
        if(foundIndex === -1){
            list.splice(foundIndex,1)
        }else if(foundIndex){
            console.log(list[i])
        }
        
    }
}

预期输出应为:

rabbit
bibe
y1aodyip

y1aodyip1#

这里有另一个解决方案,如果我们将字母“bib”排序为“bbi”。
如果我们对列表做类似的事情[“rabbit”,“bibe”,“bundle”]变成[“abbirt”,“bbei”and“bdelnu”]。如果我们过滤掉不在“bib”中的字母,列表会缩小到[“bbi”,“bbi”,“b”]。我们现在可以做的是检查结果列表中是否出现“bbi”。
下面是上面的一个中间实现:

let str = 'bib';
let list = ['rabbit','bibe','bundle'];
let str2 = [...str].sort().join('');
let result =list.filter( function (w) {
    let w2 = [...w].filter( c => str.indexOf(c) !== -1 ).sort().join('');
    return w2.indexOf(str2) !== -1;
} );
console.log(JSON.stringify(result));

下面是相同的代码,但golfed更多:

let str = 'bib';
let list = ['rabbit','bibe','bundle'];
let result = list.filter( w => [...w].filter( c => str.indexOf(c) !== -1 ).sort().join('').indexOf([...str].sort().join('')) !== -1);
console.log(JSON.stringify(result));
sg2wtvxw

sg2wtvxw2#

一个简单的解决方案是计算给定字符串中每个唯一字符的数量,然后基于此过滤元素:如果一个元素具有所有这些字符,每个字符的数量相同或更高,那么它应该被保留。
首先,声明一个helper函数:

function stringToMap(string) {
  return [...string].reduce((map, char) => {
    map[char] = map[char] + 1 || 1;
    return map;
  }, {});
}

它将返回一个对象,看起来像这样:

{
  b: 2,
  i: 1
}

Array对象有一个非常方便的方法,名为.every(),当且仅当回调函数对所有元素返回true时,该方法返回true。我们想利用它,所以我们使用Object.entries()将上面的对象转换为键值对数组:

const charsAndAmount = Object.entries(stringToMap(str));

// The object above now looks like this:
[
  ['b', 2],
  ['i', 1]
]

我们对列表中的每个元素(不是Object.entries()部分;我们不需要他们的.every()):

const charMaps = list.map(stringToMap);

[
  { r: 1, a: 1, b: 2, i: 1, t: 1 },
  { b: 2, i: 1, e: 1 },
  { b: 1, i: 1, k: 1, e: 1 },
  { b: 1, u: 1, n: 1, d: 1, l: 1, e: 1 }
]

这是最棘手的部分:对于列表中的每个单词,我们检查它是否包含给定字符串中的每个字符,每个字符的数量相同或更高。如果是,.every()将返回true.filter()将保留新列表中的单词:

const output = list.filter(
  (_, index) => charsAndAmount.every(
    ([char, number]) => number <= charMaps[index][char]
  // [ 'b',      2]       2    <=
  //           ({ r: 1, a: 1, b: 2, i: 1, t: 1 })['b']
  // 2 <= 2 === true
  )
);

试试看:

function stringToMap(string) {
  return [...string].reduce((map, char) => {
    map[char] = map[char] + 1 || 1;
    return map;
  }, {});
}

const str = 'bib';

const charsAndAmount = Object.entries(stringToMap(str));

const list = ['rabbit', 'bibe', 'bike', 'bundle'];

const charMaps = list.map(stringToMap);

const output = list.filter(
  (_, index) => charsAndAmount.every(
    ([char, number]) => number <= charMaps[index][char]
  )
);

console.log(output);
w6mmgewl

w6mmgewl3#

你可以简单地通过Array.every()方法来实现这一点,该方法测试数组中的所有元素是否通过了所提供的函数实现的测试。它返回一个Boolean值。
现场演示**:**

let str = 'bib'
let list = ['rabbit','bibe','bundle']
for(let i = 0; i < list.length; i++) {
  const allMatched = str.split('').every(e => list[i].indexOf(e) !== -1);
  if (allMatched) {
    console.log(list[i]);
  }
}

根据作者评论更新答案**:**

let str = 'bib';
let list = ['rabbit','bibe','bundle'];

const res = list.map(e => {
    return e.split('').filter(c => str.includes(c)).join('').length
});

res.forEach((matchedLength, index) => {
    if (matchedLength >= 3) {
    console.log(list[index])
  }
})

相关问题