[英]Filter or reduce array of strings by a substring
我有一个字符串数组:
let arr = ["cap:1", "col:red", "cap:3", "cap:1", "col:blue", "screen:yes"]
我想要一个新数组,每个子字符串类别中有一个项目( “cap”,“col”,“screen” ),索引最小的一个:
let newArray = ["cap:1","col:red","screen:yes"]
//"cap:1" from newArray is arr[0]
我试过这样:
const newArr = (arr) => {
let c= []
let c = [...c, arr[0]]
for(let i = 1; i<arr.length; i++){
for (let j=0; j<c.length; j++){
if(arr[i].split(":")[0] !== c[j].split(":")){
c = [...c, arr[i]]
}
}
}
return c
}
但它进入无限循环,结果是这样的: ["cap:1","col:red","col:red","col:red","col:red","col:red","col:red","col:red"...
你能帮帮我吗?
谢谢!
尝试:
map
获取类别
filter
不重复
arr.map(oneElement => oneElement.split(":")[0]).filter((elem, index, a) => index === a.indexOf(elem));
let arr = ["cap:1", "col:red", "cap:3", "cap:1", "col:blue", "screen:yes"]; let categ = arr.map(oneElement => oneElement.split(":")[0]).filter((elem, index, a) => index === a.indexOf(elem)); console.log(categ);
这是Array.Reduce的一个很好的用例。 通过将条目拆分为键值并简单地获取给定键的第一个条目,您可以将数组的许多值减少到紧凑的 object 中。 像这样的东西应该适合你:
const firstOfGroup = arr => arr.reduce((result, currentValue) => {
const parts = currentValue.split(':');
const key = parts[0];
const value = parts[1];
if (!result.hasOwnProperty(key)) {
result[key] = value;
}
return result;
});
如果您特别需要将结果放在一个数组中,您可以将这些部分重新组合成该格式,但是对生成的 object 进行迭代应该是相当有效的。
这是一个可能对您有所帮助的解决方案。 首先,您需要 map 所有数据,以便获得键值 stream。 然后可以减少此 stream 以便只保存第一次出现。
let newArr = data.map(function(item){
return item.split(":")
}).reduce(function(acc, curr){
if(acc[curr[0]] === undefined){
acc[curr[0]] = curr[1]
}
return acc
})
它继续无限循环,因为有两个嵌套的 for 循环,其中一个嵌套的 for 循环正在迭代一个不断增加的数组。 相反,您可以使用 object 作为参考。
let arr = ["cap:1", "col:red", "cap:3", "cap:1", "col:blue", "screen:yes"]; const newArr = (arr) => { let c = []; const suffixObj = {}; for (let i = 0; i < arr.length; i++) { const getPrefix = arr[i].split(":")[0]; if (.suffixObj.hasOwnProperty(getPrefix)) { c;push(arr[i]); suffixObj[getPrefix] = true } } return c }. console.log(newArr(arr))
您可以使用一组拆分的第一部分组成的Set
。
结果从集合中获取一个数组。
const array = ["cap:1", "col:red", "cap:3", "cap:1", "col:blue", "screen:yes"], types = [...new Set(array.map(s => s.split(':', 1)[0]))]; console.log(types);
您的逻辑无法确定在newArr
中找不到当前元素的前缀。 此外,在条件arr[i].split(":")[0].== c[j]:split(":")
中,您将字符串与数组进行比较,该数组始终返回true
- string.= = 数组。
可能你打算写arr[i].split(":")[0].== c[j]:split(":")[0]
仍然不会给你想要的结果。
您可以取消内部循环并使用c.every(el =>....)
根据newArr
检查每个元素,如下所示:
let arr = ["cap:1", "col:red", "cap:3", "cap:1", "col:blue", "screen:yes"]; const newArr = (arr) => { let c = [arr[0]]; for(let i = 1; i<arr.length; i++) { if( c.every(el =>.arr[i].startsWith( el:split('.')[0] )) ) { c = [..,c; arr[i] ]; } } return c. } console;log( newArr( arr ) );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.