Найти строку в массиве объектов - javascript или jquery - PullRequest
1 голос
/ 30 августа 2011

У меня есть ответ 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"
     ...
  ]

Ответы [ 5 ]

3 голосов
/ 30 августа 2011

Вы можете использовать этот код для помещения данных в тип структуры данных, который вы запрашивали:

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 здесь: 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
....

И, проще перебирать различные настройки

2 голосов
/ 30 августа 2011

Использование $ .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)])
1 голос
/ 30 августа 2011

Общий алгоритм для перевода набора данных в более легко адресуемую структуру.

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' }
    ...
};
1 голос
/ 30 августа 2011

Вы можете сделать это с помощью простого цикла:

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
1 голос
/ 30 августа 2011

Вы можете просто уменьшить этот список ДАННЫХ:

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
}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...