SQL-стиль JOIN по данным JSON
Можно ли эффективно подключиться к данным JSON? Предположим, что у нас есть два набора данных JSON:
{"COLORS":[[1,red],[2,yellow],[3,orange]]}
{"FRUITS":[[1,apple],[2,banana],[3,orange]]}
И я хочу превратить это в следующую клиентскую сторону:
{"NEW_FRUITS":[[1,apple,red],[2,banana,yellow],[3,orange,orange]]}
Имейте в виду, что здесь будут тысячи записей с гораздо более сложными структурами данных. jQuery и ванильный javascript оба хороши. Также имейте в виду, что могут быть цвета без фруктов и фруктов без цветов.
ПРИМЕЧАНИЕ. Для простоты предположим, что два набора данных находятся в одном порядке, но второй набор данных может иметь пробелы.
Ответы
Ответ 1
Нет прямого пути, но вы можете написать логику, чтобы получить объединенный объект, подобный этому. Так как "apple, red, banana...." все они являются строками, они должны быть обернуты одной или двумя кавычками.
Если вы можете сопоставить массив конфигурации COLORS и FRUITS, добавив нулевые значения для отсутствующих элементов, вы можете использовать этот подход.
Wroking демонстрация
var colors = {"COLORS":[[1,'red'],[2,'yellow'],[3,'orange']]}
var fruits = {"FRUITS":[[1,'apple'],[2,'banana'],[3,'orange']]}
var newFruits = {"NEW_FRUITS": [] }
//Just to make sure both the arrays are of same size, otherwise the logic will break
if(colors.COLORS.length == fruits.FRUITS.length){
var temp;
$.each(fruits.FRUITS, function(i){
temp = this;
temp.push(colors.COLORS[i][2]);
newFruits.NEW_FRUITS.push(temp);
});
}
Если вы можете создавать конфигурации colors
и fruits
как массив объектов вместо массива массива, вы можете попробовать это решение, которое не заботится о последовательности элементов, но размер массива должен соответствовать
Работа демонстрация
var colors = {"COLORS":[ {"1": 'red'}, { "2": 'yellow'}, {"3":'orange'}]}
var fruits = {"FRUITS":[ {"1":'apple'}, { "2": 'banana'}, {"3":'orange'}]}
var newFruits = {"NEW_FRUITS": [] }
if(colors.COLORS.length == fruits.FRUITS.length){
var temp, first;
$.each(fruits.FRUITS, function(i){
for(first in this)break;
temp = {};
temp[first] = [];
temp[first].push(this[first]);
temp[first].push(colors.COLORS[i][first]);
newFruits.NEW_FRUITS.push(temp);
});
}
Ответ 2
Тот факт, что будут тысячи вводов и ключи не обязательно, означает, что ваш лучший выбор (по крайней мере для крупных объектов) заключается в том, чтобы сначала сортировать ключ. Для объектов размером менее 5 или около того должен быть подход с грубой силой n ^ 2.
Затем вы можете записать результат, пройдя через два массива параллельно, добавив новые "записи" к вашему выходу по мере продвижения. Эта идея типа "слияние" является относительно мощной и часто используется. Если вы не хотите сортировать в первую очередь, вы можете добавить элементы в очередь приоритетов, слияния, когда вы идете. Метод sort-then-merge концептуально проще кодировать; если производительность важна, вы должны выполнить профилирование.
Для цветов без фруктов и фруктов без цветов я предполагаю, что запись null
для недостающего значения достаточно. Если один и тот же ключ появляется более одного раза в цвете или фруктах, вы можете выбрать один произвольно или выбросить исключение.
ДОБАВЛЕНИЕ Я тоже сделал скрипку: http://jsfiddle.net/LuLMz/. Он не делает никаких предположений о порядке ключей и каких-либо предположений относительно относительных длин массивов. Единственными предположениями являются имена полей и тот факт, что каждый подмассив имеет два элемента.
Ответ 3
Alasql Библиотека JavaScript SQL выполняет именно то, что вам нужно в одной строке:
<script src="alasql.min.js"></script>
<script>
var data = { COLORS: [[1,"red"],[2,"yellow"],[3,"orange"]],
FRUITS: [[1,"apple"],[2,"banana"],[3,"orange"]]};
data.NEW_FRUITS = alasql('SELECT MATRIX COLORS.[0], COLORS.[1], FRUITS.[1] AS [2] \
FROM ? AS COLORS JOIN ? AS FRUITS ON COLORS.[0] = FRUITS.[0]',
[data.COLORS, data.FRUITS]);
</script>
Вы можете играть с этим примером в jsFiddle.
Это выражение SQL, где:
- SELECT - выберите оператор
- MATRIX - модификатор, whci преобразует результаты из массива объектов в массив массивов
- ЦВЕТА. [0] - первый столбец массива COLORS и т.д.
- FRUITS. 1 AS 2 - второй столбец массива FRUITS будет сохранен как третий столбец в результирующий набор записей
- FROM? AS COLORS - массив данных из параметров с именем COLORS в выражении SQL
- ПРИСОЕДИНЯЙТЕСЬ? ON... - join
- [data.COLORS, data.FRUITS] - параметры с массивами данных