查找匹配条件的数组索引,然后推入另一个数组

时间:2018-07-25 08:54:58

标签: javascript

我正在尝试找到一种更简洁的方法来找到数组中符合条件的索引,然后将它们推入数组。我做了一些尝试,但是要么没有返回我想要的答案,要么太冗长了。

有人可以在这里阐明一些最佳的ES6方法吗?谢谢你的帮助

var arr = ["00", "000", "", "0", "000"],
  p = [];
var l = (arr.reduce((a, b) => a.length > b.length ? a : b)).length;

arr.filter(c => c.length === l); // returns ["000", "000"]
arr.map(c => c.length === l); // returns [false, true, false, false, true]
arr.map((c, i) => c.length === l ? i : c); // returns ["00", 1, "", "0", 4]
// arr.findIndex(return c.length === l) // error
function longestInstances(el) {
  return el.length == l
} // returns 1 only (after console logged)
console.log(arr.findIndex(longestInstances));
for (i = 0; i < arr.length; i++) {
  // works but verbose
  if (arr[i].length == l) {

    p.push(i);

  }

  console.log('p: ' + p);
}

3 个答案:

答案 0 :(得分:3)

我的理解是,您已经在最长的字符串arr中找到了出现最长字符串的l中的 indexes

一个简单的循环似乎是最直接的,也许使用forEach(或者当然是一个for循环,如问题所示):

var indexes = [];
arr.forEach((s,i) => {
  if (s.length === l) {
    indexes.push(i);
  }
});

实时示例:

var arr = ["00", "000", "", "0", "000"], p=[];
var l = (arr.reduce((a,b)=>a.length>b.length?a:b)).length;
var indexes = [];
arr.forEach((s,i) => {
  if (s.length === l) {
    indexes.push(i);
  }
});
console.log(indexes);

如果愿意,您可以将它塞入reduce中(可以将{em>任何内容塞入reduce中,并且人们似乎喜欢这样做),但是您不愿意这样做不能从中获得任何好处。

您还可以通过各种其他方式使它复杂化,例如创建同时具有原始值及其原始索引的对象数组,对其进行过滤,然后转换为仅索引:

var indexes = arr
  .map((string, index) => ({string, index}))
  .filter(e => e.string.length === l)
  .map(({index}) => index);

实时示例:

var arr = ["00", "000", "", "0", "000"], p=[];
var l = (arr.reduce((a,b)=>a.length>b.length?a:b)).length;
var indexes = arr
  .map((string, index) => ({string, index}))
  .filter(e => e.string.length === l)
  .map(({index}) => index);
console.log(indexes);

这避免了显式的if,并且以一种更加流式的,功能性的方式进行工作,但是确实涉及到数组的多次遍历。但是OliverRadini显示了一种更好的类似方法,尽管它仍然涉及多次通过,而简单方法仅需一次。

再说一次,除非有一些特定的原因喜欢这种流方法,简单的循环就是直接,简单,快速的方法。

答案 1 :(得分:2)

匹配条件

此答案假定您要获取的元素的索引与数组中具有最大长度的元素的长度相等。


获取指数

要获取最长元素的长度,我们首先获取每个元素的长度,然后缩小数组以仅获取最大长度。

接下来,我们将数组的每个元素映射到以下两种情况之一:如果元素的长度与最大长度相同,则取其索引。如果不是,则改为映射false。我们这样做是为了过滤掉那些值。

最后,我们过滤掉错误的值。这些值不如最大长度那么长,所以我们不希望它们。


正如T.J.Crowder所暗示的,forEach可能以更直接,更可能可读的方式进行此操作。以这种方式尝试链接数组方法将使您能够对哪种类型的代码做出最佳决定,这种代码最适合您所面对的情况。

如果要处理非常大的数据集,则多次迭代数据以提高代码的可读性(以牺牲性能为代价)可能不是一个好主意。

const arr = ["00", "000", "", "0", "000"]

const maxLength = arr
  .map(e => e.length)
  .reduce((a, b) => a > b ? a : b)
  
const result = arr
  .map((val, i) => val.length === maxLength ? i : false) // log the index of the item if the item's length is 1
  .filter(i => i !== false) // remove non-truthy elements
  
console.dir(result)

答案 2 :(得分:1)

您可以通过获取与长度条件匹配的索引来缩小数组。

var array = ["00", "000", "", "0", "000"],
    indices = array.reduce((r, s, i, a) => {
        if (!r || s.length > a[r[0]].length) { // check initial or greater length
            return [i];
        }
        if (s.length === a[r[0]].length) {     // check same length
            r.push(i);
        }
        return r;
    }, undefined);
    
console.log(indices); // [1, 4]