【问题标题】:Get elements from array untill a condition matches从数组中获取元素,直到条件匹配
【发布时间】:2016-01-12 05:24:10
【问题描述】:

我有一个这样的数组

var arr = [
    "/a_3312368_392921_800MHz", 
    "/a_3312368_392853_900MHz", 
    "/a_3312368_578261_1GHz", 
    "/a_3312368_578189_120GHz", 
    "/a_3312368_578167_140GHz", 
    "/a_3312368_578230_160GHz", 
    "/a_3312368_578192_180GHz", 
    "/a_3312368_397393_183GHz", 
    "/a_3312368_582870_186GHz", 
    "/a_3312368_578174_190GHz", 
    "/a_3312368_578177_2GHz", 
    "/a_3312368_578922_210GHz", 
    "/a_3312368_578479_220GHz", 
    "/a_3312368_578357_226GHz", 
    "/a_3312368_578182_240GHz", 
    "/a_3312368_578919_250GHz", 
    "/a_3312368_578349_253GHz", 
    "/a_3312368_578639_280GHz", 
    "/a_3312368_579178_3GHz"
];

我需要从操作员选择中获得价值。我有一些这样的运营商

`> , < , = , <= , >=`

这里是选择的值,例如

var selection = "/a_3312368_578189_120GHz";

例如我当前的操作员

var operator = ">";

这是我写的一些代码。

var string_array = [];
for(var i = 0; i < arr.length; i++){
    if(selection == arr[i]){
        break;
    }
    string_array.push(arr[i]);
}
console.log(string_array);

它给了我正确的结果。但是当我用地图尝试它时,它会产生错误Can't have break outside of loop

string_array = arr.map(function(item) {  if (selection == item){ break; }  else {return item;} });

我怎样才能为此编写一行代码。

Fiddle Link

【问题讨论】:

  • 使用Array.prototype.some.every 迭代直到条件返回真或假。
  • @RobG 但他们不会“自动”构造数组...
  • One liner 不应该是你的设计目标。可读、可维护的代码应该是。作为次要目标,性能(早期中断对于大数据至关重要。for(...) { ...} 优于数组迭代函数)
  • @RobG 要求是一个班轮some/every 不适合这里的账单。
  • map 返回数组元素数相同,需要filter,或者reduce

标签: javascript loops search dictionary


【解决方案1】:

嗯……你不能破坏地图。不要使用map。使用someevery

示例 - some: - 当回调返回 true 时,some 将中断

arr.some(function (item) {if (selection == item) {return true;}});    

var selection = "/a_3312368_578189_120GHz";
var arr = ["/a_3312368_392921_800MHz", "/a_3312368_392853_900MHz", "/a_3312368_578261_1GHz", 
    "/a_3312368_578189_120GHz", "/a_3312368_578167_140GHz", "/a_3312368_578230_160GHz", 
    "/a_3312368_578192_180GHz", "/a_3312368_397393_183GHz", "/a_3312368_582870_186GHz", 
    "/a_3312368_578174_190GHz", "/a_3312368_578177_2GHz", "/a_3312368_578922_210GHz", 
    "/a_3312368_578479_220GHz", "/a_3312368_578357_226GHz", "/a_3312368_578182_240GHz", 
    "/a_3312368_578919_250GHz", "/a_3312368_578349_253GHz", "/a_3312368_578639_280GHz", 
    "/a_3312368_579178_3GHz"
];

string_array =  [];
arr.some(function(item) { if (selection == item){ return true; }else{string_array.push(item);}
});
console.log(string_array);

Example-every: - 当回调返回 false 时,every 将中断

arr.every(function(item) { if (selection == item) {return false;}});  

var selection = "/a_3312368_578189_120GHz";
var arr = ["/a_3312368_392921_800MHz", "/a_3312368_392853_900MHz", "/a_3312368_578261_1GHz", 
    "/a_3312368_578189_120GHz", "/a_3312368_578167_140GHz", "/a_3312368_578230_160GHz", 
    "/a_3312368_578192_180GHz", "/a_3312368_397393_183GHz", "/a_3312368_582870_186GHz", 
    "/a_3312368_578174_190GHz", "/a_3312368_578177_2GHz", "/a_3312368_578922_210GHz", 
    "/a_3312368_578479_220GHz", "/a_3312368_578357_226GHz", "/a_3312368_578182_240GHz", 
    "/a_3312368_578919_250GHz", "/a_3312368_578349_253GHz", "/a_3312368_578639_280GHz", 
    "/a_3312368_579178_3GHz"
];

string_array = [];
arr.every(function(item) {if (selection != item){string_array.push(item);} return item.indexOf(selection) == -1;
});

console.log(string_array);

【讨论】:

  • 为什么要保留for循环?
【解决方案2】:

当您使用map 时,结果数组的元素计数与源相同。
你想要的只是过滤数组,所以使用filter函数。

如果你的源数组排序器,那么操作符只显示与所选元素索引的关系。

所以你的代码应该是这样的

var selection = "/a_3312368_578189_120GHz";
var indexSelected = arr.indexOf(selection)
string_array = arr.filter(function(el, index){
    return index < indexSelected;
});

var arr = [
    "/a_3312368_392921_800MHz", 
    "/a_3312368_392853_900MHz", 
    "/a_3312368_578261_1GHz", 
    "/a_3312368_578189_120GHz", 
    "/a_3312368_578167_140GHz", 
    "/a_3312368_578230_160GHz", 
    "/a_3312368_578192_180GHz", 
    "/a_3312368_397393_183GHz", 
    "/a_3312368_582870_186GHz", 
    "/a_3312368_578174_190GHz", 
    "/a_3312368_578177_2GHz", 
    "/a_3312368_578922_210GHz", 
    "/a_3312368_578479_220GHz", 
    "/a_3312368_578357_226GHz", 
    "/a_3312368_578182_240GHz", 
    "/a_3312368_578919_250GHz", 
    "/a_3312368_578349_253GHz", 
    "/a_3312368_578639_280GHz", 
    "/a_3312368_579178_3GHz"
];
var selection = "/a_3312368_578189_120GHz";
var indexSelected = arr.indexOf(selection);
var string_array = arr.filter(function(el,index){
  return index < indexSelected;
  });

document.getElementById('r').innerHTML = JSON.stringify(string_array,null, 2);
&lt;pre id="r"&gt;&lt;/pre&gt;

正如评论中的@Toffy 所说——在你的情况下,你似乎需要简单的slice

var indexSelected = arr.indexOf(selection)
string_array = arr.slice(0,indexSelected);

var arr = [
    "/a_3312368_392921_800MHz", 
    "/a_3312368_392853_900MHz", 
    "/a_3312368_578261_1GHz", 
    "/a_3312368_578189_120GHz", 
    "/a_3312368_578167_140GHz", 
    "/a_3312368_578230_160GHz", 
    "/a_3312368_578192_180GHz", 
    "/a_3312368_397393_183GHz", 
    "/a_3312368_582870_186GHz", 
    "/a_3312368_578174_190GHz", 
    "/a_3312368_578177_2GHz", 
    "/a_3312368_578922_210GHz", 
    "/a_3312368_578479_220GHz", 
    "/a_3312368_578357_226GHz", 
    "/a_3312368_578182_240GHz", 
    "/a_3312368_578919_250GHz", 
    "/a_3312368_578349_253GHz", 
    "/a_3312368_578639_280GHz", 
    "/a_3312368_579178_3GHz"
];
var selection = "/a_3312368_578189_120GHz";
var indexSelected = arr.indexOf(selection);
var string_array = arr.slice(0,indexSelected);

document.getElementById('r').innerHTML = JSON.stringify(string_array,null, 2);
&lt;pre id="r"&gt;&lt;/pre&gt;

源数组未排序时的示例

var selection = "/a_3312368_578189_120GHz";
var selectedFreq = getFreq(selection);

function getFreq(s) {
    var parts = s.match(/(\d+)(MHz|GHz)$/);
    return parts[1]* (parts[2] == "GHz" ? 1000: 1);    
}
var string_array = arr.filter(function(el) {
    var elFreq = getFreq(el);
    return selectedFreq > elFreq;
});

var arr = [
  "/a_3312368_392921_800MHz",
  "/a_3312368_392853_900MHz",
  "/a_3312368_578261_1GHz",
  "/a_3312368_578922_210GHz",
  "/a_3312368_578479_220GHz",
  "/a_3312368_578357_226GHz",
  "/a_3312368_578182_240GHz",
  "/a_3312368_578919_250GHz",
  "/a_3312368_578349_253GHz",
  "/a_3312368_578639_280GHz",
  "/a_3312368_579178_3GHz",
  "/a_3312368_578189_120GHz",
  "/a_3312368_578167_140GHz",
  "/a_3312368_578230_160GHz",
  "/a_3312368_578192_180GHz",
  "/a_3312368_397393_183GHz",
  "/a_3312368_582870_186GHz",
  "/a_3312368_578174_190GHz",
  "/a_3312368_578177_2GHz",
];
var selection = "/a_3312368_578189_120GHz";
var selectedFreq = getFreq(selection);

function getFreq(s) {
  var parts = s.match(/(\d+)(MHz|GHz)$/);
  return parts[1]* (parts[2] == "GHz" ? 1000: 1);    
}
var string_array = arr.filter(function(el) {
    var elFreq = getFreq(el);
    return selectedFreq > elFreq;
});

document.getElementById('r').innerHTML = JSON.stringify(string_array, null, 2);
&lt;pre id="r"&gt;&lt;/pre&gt;

【讨论】:

  • 你为什么要重新实现 array.slice() 这不是我的反对意见?
  • OPs 代码更短、更快并且 - imo - 更易于解释。
  • @Touffy,因为过滤器中的条件可能更复杂
  • 反对票非常苛刻,Grundy 的回答毕竟有效。
  • @Ben — indexOf 没有理由必须使用循环。一个实现可以在添加成员时建立一个索引,或者保留一个易于搜索的可搜索、排序对象,或者……等等。查看performance,Chrome 似乎已经进行了优化,因此 indexOf 比循环快得多。其他浏览器没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 2013-10-04
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
相关资源
最近更新 更多