什么是最好的方法 - 正则表达式或其他什么?
我有以下数组:
[
"b1:number/1",
"b1:number/1/chest/85",
"b1:number/1/height/175",
"b1:number/1/hip/90",
"b1:number/1/category/bottoms/size_2/m",
"b1:number/1/category/bottoms/size_1/m",
"b1:number/1/category/bottoms/size_3/s",
]
我需要从入门开始采取品牌b1" b1:" 这应解析如下:
{
"number": 1,
"category": "bottoms",
"height": "175",
"chest": 85,
"brand": "b1",
"hip": 90,
"size_1": "m",
"size_2": "m",
"size_3": "s"
}
编辑: 我只需要解析以" b1:number /"开头的数据。包括像
这样的数据[
"b1:another/somethingElse", //SHOULD NOT BE CONSIDERED
"b1:number/1",
"b1:number/1/chest/85",
"b1:number/1/height/175",
"b1:number/1/hip/90",
"b1:number/1/category/bottoms/size_2/m",
"b1:number/1/category/bottoms/size_1/m",
"b1:number/1/category/bottoms/size_3/s",
]
答案 0 :(得分:2)
通常,如果没有对输入格式的良好描述,代码中会有很多假设。以下是我所做的一些值得一提的假设:
split[2] == 'category'
并使用不匹配的字符串执行其他操作。以下是代码:
data = [
"b1:number/1",
"b1:number/1/chest/85",
"b1:number/1/height/175",
"b1:number/1/hip/90",
"b1:number/1/category/bottoms/size_2/m",
"b1:number/1/category/bottoms/size_1/m",
"b1:number/1/category/bottoms/size_3/s",
];
var properties = {};
properties.brand = data[0].substr(0, 2);
for (var i = 0; i < data.length; i++) {
var split = data[i].split('/');
var category = null;
// Skip entries that don't have any real data
if (split.length > 2) {
if (split.length < 6) {
// e.g. b1:number/1/chest/85
properties[split[2]] = parseInt(split[3]);
} else {
// e.g. b1:number/1/category/bottoms/size_1/m
properties.category = split[3]; // e.g. bottoms
properties[split[4]] = split[5]; // e.g. size_1, m
}
} else if (split[0].split(':')[1] === 'number') {
properties.number = split[1];
}
}
console.log(properties);
// Output:
// { brand: 'b1',
// number: '1',
// chest: 85,
// height: 175,
// hip: 90,
// category: 'bottoms',
// size_2: 'm',
// size_1: 'm',
// size_3: 's' }
答案 1 :(得分:1)
我的想法是使用.reduce()
来处理数组中的每个元素,并将其值添加到对象中。我/
字符上的每个项目.split()
,然后测试生成了多少件,以便确定如何处理它。
function processItem(item) {
return item.reduce(function(a, v) {
var parts = v.split("/");
var b = parts[0].split(":");
if (b[1] === "number") {
switch(parts.length) {
case 2:
a[b[1]] = parts[1];
a.brand = b[0];
break;
case 4:
a[parts[2]] = +parts[3]; // note unary plus to convert to number
break;
case 6:
if (!a[parts[2]])
a[parts[2]] = parts[3];
a[parts[4]] = parts[5];
break;
}
}
return a;
}, {});
}
console.log(processItem([
"b1:another/somethingElse",
"b1:number/1",
"b1:number/1/chest/85",
"b1:number/1/height/175",
"b1:number/1/hip/90",
"b1:another/blah",
"b1:number/1/category/bottoms/size_2/m",
"b1:number/1/category/bottoms/size_1/m",
"b1:number/1/category/bottoms/size_3/s",
]));
&#13;
答案 2 :(得分:1)
没有任何正则表达式,我可以按照以下方式执行;
var data = [
"b1:number/1",
"b1:number/1/chest/85",
"b1:number/1/height/175",
"b1:number/1/hip/90",
"b1:number/1/category/bottoms/size_2/m",
"b1:number/1/category/bottoms/size_1/m",
"b1:number/1/category/bottoms/size_3/s",
"b1:notnumber/1/category/bottoms/size_4/xs"
],
dataObj = data.map(e => e.split(":"))
.map(e => ["brand",e[0]].concat(e[1].indexOf("number") === 0 ? e[1].split("/") :[]))
.map(e => e.reduce((p,c,i,a) => i%2 === 0 ? (p[c] = a[i+1],p) : p,{}))
.reduce((p,c) => Object.assign(p,c));
console.log(dataObj);
代码说明:
.map(e => e.split(":"))
这将逐个处理数据数组的每个元素,从":"
字符中拆分字符串项,并将每个子字符串放入一个新数组中。因此输入数组将转换为像[["b1","number/1"],["b1","number/1/chest/85"],..., ["b1",notnumber/1/category/bottoms/size_4/xs"]]
.map(e => ["brand",e[0]].concat(e[1].indexOf("number") === 0 ? e[1].split("/") :[]))
这是一个非常复杂的部分。每个数据数组项都是由地图仿函数中的e[0]
和e[1]
指定的两个元素的数组。我们将构造一个数组,其中偶数索引处的项目将用于目标对象的属性,奇数索引处的项目将用作值。因此,我们从数组["brand",e[0]]
开始,其中e[0]
在此特定情况下为"b1"
。然后,如果e[1]
处的字符串以"number"
(e[1].indexOf("number") === 0
)开头,那么我们将"/"
字符拆分为数组。 (e[1].split("/")
)并获取"number/1/category/bottoms/size_2/m"
- &gt; ["number", "1", "category", "bottoms", "size_2", "m"]
但如果它不是以"number"
开头,那么我们使用空数组[]
。最后,我们将从e[0]
和e[1]
.map(e => e.reduce((p,c,i,a) => i%2 === 0 ? (p[c] = a[i+1],p) : p,{}))
这是在上述阶段获得的阵列上的标准减少操作。我们正在使用{}
的初始值(空对象)进行缩减。偶数索引位置(i%2 === 0
)的每个项目都作为属性添加到我们的初始对象中,并且以下属性被添加为此属性p[c] = a[i+1]
的值。然后我们返回p来提供reduce迭代的下一个阶段。 ,p) : p
.reduce((p,c) => Object.assign(p,c));
现在我们拥有数据数组中每个项目的对象。我们将它们整合为一体。 Object.assign()
是完成这项工作的理想工具。
最后我们在链的末尾返回结果。
答案 3 :(得分:0)
您的输入数据和结果有一个模式,因此这是一个转换操作。由于输入非常简单,您可以简单地使用split
函数切割成片段,然后构建输出。
请注意,您还需要进行类型转换和必要的验证。例如,高度是数字,所以不要忘记拨打Number
。
function numOrStr(s) {
return isNaN(s) ? s : Number(s)
}
function convert(input) {
try {
var arr = input[0].split(':')
var brand = arr[0]
arr = arr[1].split('/')
var result = {
brand: brand,
number: Number(arr[1])
}
input.slice(1).forEach(function(item) {
item = item.substr((input[0] + '/').length)
var arr = item.split('/')
if (arr[0] === 'category') {
result['category'] = arr[1]
result[arr[2]] = numOrStr(arr[3])
} else {
result[arr[0]] = numOrStr(arr[1])
}
})
return result
} catch (ex) {
console.error({msg: 'invalid input object', data: input})
}
}
var input = [
"b1:number/1",
"b1:number/1/chest/85",
"b1:number/1/height/175",
"b1:number/1/hip/90",
"b1:number/1/category/bottoms/size_2/m",
"b1:number/1/category/bottoms/size_1/m",
"b1:number/1/category/bottoms/size_3/s",
]
var output = convert(input)
console.log(output)
&#13;
答案 4 :(得分:0)
这是纯粹的PHP方法:
<?php
$arr_ = [
"number/1",
"number/1/chest/85",
"number/1/height/175",
"number/1/hip/90",
"number/1/category/bottoms/size_2/m",
"number/1/category/bottoms/size_1/m",
"number/1/category/bottoms/size_3/s",
];
$arr_values = array();
for($i=0; $i <count($arr_); $i++){
$arr_data = explode("/", $arr_[$i]);
for($j=0; $j<count($arr_data); $j++){
if(!is_null($arr_data[($j + 1)])){
if(!in_array(array($arr_data[$j] => $arr_data[$j + 1]), $arr_values)){
array_push($arr_values, array($arr_data[$j] => $arr_data[($j + 1)]));
}
}
$j++;
}
}
echo json_encode($arr_values);
输出:
[{"number":"1"},{"chest":"85"},{"height":"175"},{"hip":"90"},{"category":"bottoms"},{"size_2":"m"},{"size_1":"m"},{"size_3":"s"}]
答案 5 :(得分:0)
这对正则表达式来说看起来不错。 将数组转换为js对象可以通过以下方式完成:
查找以b1开头的每个数组元素:number并忽略其他数组
\"(((?=b1:number).*[:,/](.*)\/(.*))|(?!>b1:number).*)\"
然后使用最后两组 - 最后一次斜线前后 - 替换
"$3":"$4"
它将生成js对象 - 仍然包裹在数组括号中,并带有空的“属性”
[ "":"", "number":"1", "chest":"85", "height":"175", "hip":"90", "size_2":"m", "size_1":"m", "size_3":"s", ]
然后用卷曲替换数组括号:
"[test]".replace("[", "{").replace("]","}").replace(/"":"",/g, "");;
最后,如果需要js,你需要你的自定义逻辑来处理正确的数据类型。