在对象数组中查找字符串- javascript或jquery

Find string in array of objects- javascript or jquery

本文关键字:javascript jquery 字符串 查找 对象 数组      更新时间:2023-09-26

JSON响应如下所示:

{
    "COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
    "DATA": [
                ["setting_1",100.0,"yellow"],
                ["setting_2",150.0,"red"],
                ["setting_3",30.0,"green"],
                ["setting_4",11.0,"blue"]
            ]
 }

我如何找到设置'setting_4'的'颜色'?可接受的解决方案要么是访问数据的简单方法,要么是将其转换为像

这样的爆炸键/值数组的函数。
 [
     setting_1_value: '100', 
     setting_1_color: 'yellow', 
     setting_2_value: "150"
     ...
  ]

您可以使用以下代码将数据放入您所要求的数据结构类型中:

var response = {"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
"DATA":[["setting_1",100.0,"yellow"],["setting_2",150.0,"red"],
["setting_3",30.0,"green"],["setting_4",11.0,"blue"]]};
var data = response.DATA;
var columns = response.COLUMNS;
var hash = {}, item, name, i;
var cols = {};
// remember order of columns
for (i = 0; i < columns.length; i++) {
    cols[columns[i]] = i;
}
// fetch data from correct column
for (i = 0; i < data.length; i++) {
    item = data[i];
    name = item[cols["SETTING_NAME"]];
    hash[name + "_value"] = item[cols["SETTING_VALUE"]];
    hash[name + "_color"] = item[cols["COLOR"]];
}
hash.num = data.length;

正如你所要求的,这给了你一个这样的数据结构,这样你就可以直接读取你想要的任何值:

{
    "setting_1_value":100,
    "setting_1_color":"yellow",
    "setting_2_value":150,
    "setting_2_color":"red",
    "setting_3_value":30,
    "setting_3_color":"green",
    "setting_4_value":11,
    "setting_4_color":"blue",
    "num":4
}

jsFiddle here: http://jsfiddle.net/jfriend00/HZmYN/生成这个结果。

就我个人而言,我更愿意使用以下代码将其解析为这种类型的数据结构:

var response = {"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
"DATA":[["setting_1",100.0,"yellow"],["setting_2",150.0,"red"],
["setting_3",30.0,"green"],["setting_4",11.0,"blue"]]};
var data = response.DATA;
var columns = response.COLUMNS;
var newData = [], item, obj, i, num, match;
var cols = {};
// remember order of columns
for (i = 0; i < columns.length; i++) {
    cols[columns[i]] = i;
}
for (i = 0; i < data.length; i++) {
    item = data[i];
    obj = {};
    obj.value = item[cols["SETTING_VALUE"]];
    obj.color = item[cols["COLOR"]];
    obj.name = item[cols["SETTING_NAME"]];
    match = obj.name.match(/'d+$/);
    if (match && match.length > 0) {
        obj.settingNumber = parseInt(match[0], 10);
    }
    newData.push(obj);
}
// now sort the array by the number in the name setting
newData.sort(function(a, b) {
    return(a.settingNumber- b.settingNumber);
});

生成如下数据结构:

[
  {"value":100,"color":"yellow","name":"setting_1","settingNumber":1},
  {"value":150,"color":"red","name":"setting_2","settingNumber":2},
  {"value":30,"color":"green","name":"setting_3","settingNumber":3},
  {"value":11,"color":"blue","name":"setting_4","settingNumber":4}
]

图示jsFiddle: http://jsfiddle.net/jfriend00/A23Jd/.

我喜欢这种结构的原因是,你可以更容易地访问"n"设置作为一个对象数组:

newData[0].color
newData[0].value
newData[0].name
newData[1].color
....

并且,更容易遍历各种设置

Using $。Grep将允许您访问数据而不需要在之前对它们进行映射:

var json={"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
          "DATA":[["setting_1",100.0,"yellow"],
                  ["setting_2",150.0,"red"],
                  ["setting_3",30.0,"green"],
                  ["setting_4",11.0,"blue"]]}
alert($.grep(json.DATA, function(item){return(item[0]=='setting_4');})[0][2])//returns 'blue'
//or using the labels provided by COLUMNS:
alert($.grep(json.DATA, 
             function(a){return(a[0]=='setting_4');})[0][$.inArray('COLOR',json.COLUMNS)])

可以通过一个简单的for循环来实现:

var obj = {"COLUMNS":["SETTING_NAME","SETTING_VALUE","COLOR"],
"DATA":[["setting_1",100.0,"yellow"],["setting_2",150.0,"red"],
["setting_3",30.0,"green"],["setting_4",11.0,"blue"]]};
for(var i = 0; i < obj.DATA.length; i++)
{
    var row = obj.DATA[i]
    if (row[0] == 'setting_4')
    {
        console.log(row[2]);
        break;
    }
}

打印:

blue

您可以简单地减少数据列表:

DATA.reduce(function (value, item) { if (item[0] === "setting_4") return item[2] })

您可以将整个内容包装成一个函数以便于使用,传递"setting_4"部分。例如

var getColour = function (id) {
  return DATA.reduce(function (value, item) {
    if (item[0] === id) return item[2]
  })
}

更新:你可以把两个列表压缩在一起,也许这样会更容易访问?

obj['DATA'].map(function (row) {
  return obj['COLUMNS'].reduce(function (memo, columnName, index) {
    memo[columnName] = row[index]
    return memo
  }, {})
})

这将返回如下内容:

[{
   COLOR: "yellow",
   SETTING_NAME: "setting_1",
   SETTING_VALUE: 100
}]

将数据集转换为更容易寻址的结构的通用算法。

var json = {
    "COLUMNS": [
        "SETTING_NAME",
        "SETTING_VALUE",
        "COLOR"],
    "DATA": [
        ["setting_1",100.0,"yellow"],
        ["setting_2",150.0,"red"],
        ["setting_3",30.0,"green"],
        ["setting_4",11.0,"blue"]
    ]
};
function translateJSON(json) {
    var oHash = {};
    var data = json['DATA'];
    var cols = json['COLUMNS'];
    for(var i = 0, imax = data.length; i < imax; i++) {
        var row = data[i]; // shorthand
        for(var j = 1, jmax = cols.length; j < jmax; j++) {
            var c = cols[j]; // shorthand
            oHash[(row[0] + '_' + c.replace(/[^_]+_/, '')).toLowerCase()] = row[j];
        }
    }
    return oHash;
}
var h = translateJSON(json);
console.log(h['setting_4_color']);

编辑:更新代码。translateJSON将把JSON转换为您描述的数据结构,以便更容易地访问属性。如果您预计需要从相同的JSON负载访问多个属性,那么在数据访问之前进行一次性转换将比使用$.grep更有效,并且比手工进行列名交叉引用要简洁得多。

也就是说,我不认为你要求的目标数据结构一定是最好的。假设您不能更改JSON有效负载的结构,那么将其转换为以下格式可能会更好:

data = {
    'setting_1': { 'value': 100.0, 'color': 'yellow' },
    'setting_2': { 'value': 150.0, 'color': 'red' }
    ...
};