2017-01-11 2 views
1

Я пытаюсь отобразить таблицу со сравнением некоторых элементов. Идея заключается в том, чтобы разобраться в правильном пути (меньше на левом и более полного справа), как:Сортировка Json по реквизитам дочерних элементов (таблица сравнения)

   Plan1 | Plan2 | Plan3 
item1   X  X   X 
item2   -  X   X 
item3   -  -   X 

Но API нашего поставщика служит JSON неупорядоченным. Проблема в том, что у нас есть более 100 наименований и почти 20 планов, поэтому его невозможно фильтровать по «жесткому коду».

JSON колоссальная, поэтому простая версия только с минимумом будет (как в этом примере):

[ 
    { 
     "Id": "1", 
     "Name": "Item1", 
     "Plans": [ 
      { 
       "PlanMaster": "EPTV Max", 
       "IdPlan": 1000, 
       "HasPlan": true 
      }, 
      { 
       "PlanMaster": "EPTV", 
       "IdPlan": 1001, 
       "HasPlan": true 
      }, 
      { 
       "PlanMaster": "Web TV", 
       "IdPlan": 1002, 
       "HasPlan": true 
      } 
     ] 
    }, 
    { 
     "Id": "2", 
     "Name": "Item2", 
     "Plans": [ 
      { 
       "PlanMaster": "EPTV Max", 
       "IdPlan": 1000, 
       "HasPlan": false 
      }, 
      { 
       "PlanMaster": "EPTV", 
       "IdPlan": 1001, 
       "HasPlan": true 
      }, 
      { 
       "PlanMaster": "Web TV", 
       "IdPlan": 1002, 
       "HasPlan": true 
      } 
     ] 
    }, 
    { 
     "Id": "3", 
     "Name": "Item3", 
     "Plans": [ 
      { 
       "PlanMaster": "EPTV Max", 
       "IdPlan": 1000, 
       "HasPlan": false 
      }, 
      { 
       "PlanMaster": "EPTV", 
       "IdPlan": 1001, 
       "HasPlan": false 
      }, 
      { 
       "PlanMaster": "Web TV", 
       "IdPlan": 1002, 
       "HasPlan": true 
      } 
     ] 
    } 
] 

Дело в том, как я могу перемещаться по JSON для запроса несколько вещей, таких как «Как многие планы, которые у меня есть »,« Список планов в порядке уменьшения количества и т.д. »и т. д.

Как называется эта проблема« сортировки »/« сравнения »? Я пытался сортировать google и т. Д. ... и не мог найти много. Я просто хочу знать, как я могу запросить узлы в javascript, чтобы я мог реализовать логику.

веселит

+0

Вам нужно будет создать свой собственный алгоритм сортировки/логику, инкапсулированный в [.sort] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ метод сортировки). – mrlew

ответ

1

Вы можете рассматривать планы как двоичное число и использовать его как критерий сортировки.

var data = [{ "Id": "1", "Name": "Item1", "Plans": [{ "PlanMaster": "EPTV Max", "IdPlan": 1000, "HasPlan": true }, { "PlanMaster": "EPTV", "IdPlan": 1001, "HasPlan": true }, { "PlanMaster": "Web TV", "IdPlan": 1002, "HasPlan": true }] }, { "Id": "2", "Name": "Item2", "Plans": [{ "PlanMaster": "EPTV Max", "IdPlan": 1000, "HasPlan": false }, { "PlanMaster": "EPTV", "IdPlan": 1001, "HasPlan": true }, { "PlanMaster": "Web TV", "IdPlan": 1002, "HasPlan": true }] }, { "Id": "3", "Name": "Item3", "Plans": [{ "PlanMaster": "EPTV Max", "IdPlan": 1000, "HasPlan": false }, { "PlanMaster": "EPTV", "IdPlan": 1001, "HasPlan": false }, { "PlanMaster": "Web TV", "IdPlan": 1002, "HasPlan": true }] }]; 
 

 
data.sort(function (a, b) { 
 
    function getRange(o) { 
 
     var r = o.Plans.reduce(function (r, a) { 
 
       return r * 2 + !a.HasPlan; 
 
      }, 0); 
 
     
 
     o.r = r; // just to show what's happen 
 
     return r; 
 
    } 
 

 
    return getRange(a) - getRange(b); 
 
}); 
 

 
console.log(data)
.as-console-wrapper { max-height: 100% !important; top: 0; }

+1

Работал как шарм! Я поместил несколько иены в другом порядке, и он правильно отсортировался. Спасибо, Нина! – 2Fast4YouBR

1

Вы можете определить общую функцию, которая сортирует массив, основанный на некоторой key функции:

let sortBy = (a, key) => a 
    .map(x => [key(x), x]) 
    .sort((x, y) => x[0] > y[0] ? 1 : x[0] < y[0] ? -1 : 0) 
    .map(x => x[1]); 

затем написать некоторые конкретные задачи ключевые функции, например:

let numberOfPlans = item => item.Plans.filter(x => x.HasPlan).length; 

и передать их на адрес sortBy:

let sortedData = sortBy(data, numberOfPlans); 

Другим (и, возможно, лучшим) вариантом было бы загрузить эти данные в реляционную базу данных (например, sqlite) и использовать всю мощь SQL, чтобы получить все, что вам нужно.

1

Вы собираетесь должны использовать цикл в любом случае. Если ваш JSON такой же большой, как вы его делаете, эффективность - это проблема. Вы должны сделать все возможное, чтобы повысить эффективность.

Однако, если ваш JSON имеет 100 элементов (как вы говорите), это действительно не так уж и много для набора данных. Набор данных с миллионами строк? Конечно. Но сто или даже несколько тысяч, вероятно, не будут представлять значительную часть проблем с первичным доступом (очевидно, это также результат того, сколько вложенных свойств есть в каждом элементе вашего набора данных).

Что касается «навигации» JSON, вам нужен просто цикл через них в качестве объектов и избежать многих аксессоров, как вы можете (поиск в кэше, и т.д.).

Я редко поклонник Аппаратно кодирование проверяет, где цикл будет лучше, но имейте в виду, что в некоторых случаях это допустимо, если вы абсолютно точно знаете, что такое ваш набор данных, а преимущества персинга превышают преимущества обслуживания.

пример чего-то, что является более перфорация дружественный, но менее удобны в обслуживании:

var i; 
var j; 
//Set up a 2-dimensional array where each array index represents the number of plans that each of it's members has. In this case, numPlans[0] contains all items that contain 0 plans, etc. 
var plans = [[], [], []]; 
//Don't re-create variables on every loop, just re-assign 
var item; 
var numPlans; 
var p; 

for(i = 0; i < data.length; i++){ 
    item = data[i]; 
    p = item.Plans; 
    numPlans = 0; 
    for(j = 0; j < p.length; j++) { 
     if(p[j].HasPlan) { 
      numPlans++; 
     } 
    } 
    plans[numPlans].push(item); 
} 

Это не тестировался, но это грубо проект довольно парфюм-ориентированный подход.

Смежные вопросы