#javascript #node.js #reactjs #typescript
Вопрос:
Мне нужно отсортировать вложенный массив в порядке сортировки, и ключ сортировки будет динамическим. Я использую запрос, но он работает только с обычным текстом. Примеры Данных:
[ { "modelId":1, "modelCode":"model1", "price":[ { "PRICE_CODE1":225.01 }, { "PRICE_CODE2":247.68 }, { "PRICE_CODE3":298.0 } ] }, { "modelId":2, "modelCode":"model2", "price":[ { "PRICE_CODE1":100.01 }, { "PRICE_CODE2":200.68 }, { "PRICE_CODE3":300.0 } ] } ]
Ожидаемый Результат:
[ { "modelId":2, "modelCode":"model2", "price":[ { "PRICE_CODE1":100.01 }, { "PRICE_CODE2":200.68 }, { "PRICE_CODE3":300.0 } ] }, { "modelId":1, "modelCode":"model1", "price":[ { "PRICE_CODE1":225.01 }, { "PRICE_CODE2":247.68 }, { "PRICE_CODE3":298.0 } ] } ]
в соответствии с приведенным выше примером сортировка-это PRICE_CODE1, код модели в порядке возрастания. Я использую следующий запрос-
function sortByMultipleKey(keys) { return function(a, b) { if (keys.length == 0) return 0; // force to equal if keys run out key = keys[0]; // take out the first key if (a[key] lt; b[key]) return -1; // will be 1 if DESC else if (a[key] gt; b[key]) return 1; // will be -1 if DESC else return sortByMultipleKey(keys.slice(1))(a, b); } } arr.sort(sortByMultipleKey(['PRICE_CODE1','modelCode']))
приведенный выше запрос работает для простых массивов, а не для массивов массивов, потому что в примере цена-это массив. Как этого добиться?
Комментарии:
1. какое значение вы принимаете для сравнения?
2. PRICE_CODE1, код модели
3. который
PRICE_CODE1
?4. в приведенном выше JSON PRICE_CODE1 является ключом внутри массива цен. сравнение объекта один
5. да, я знаю. но какой из них вы берете для сравнения объекта один и два?
Ответ №1:
Внимание: Это будет работать для структуры массива цен, которая у вас есть, но не для кода модели в качестве ключа сортировки.
const data = [ { "modelId":2, "modelCode":"model2", "price":[ { "PRICE_CODE1":100.01 }, { "PRICE_CODE2":200.68 }, { "PRICE_CODE3":300.0 } ] }, { "modelId":1, "modelCode":"model1", "price":[ { "PRICE_CODE1":225.01 }, { "PRICE_CODE2":247.68 }, { "PRICE_CODE3":298.0 } ] } ] function sortData(sortKeys = []) { data.sort((a,b) =gt; { for (let sortKey of sortKeys) { const priceObjA = a.price.find(x =gt; sortKey in x); const priceObjB = b.price.find(x =gt; sortKey in x); const priceA = priceObjA amp;amp; priceObjA[sortKey] || 0; const priceB = priceObjB amp;amp; priceObjB[sortKey] || 0; const result = priceA - priceB; if (result !== 0) { return result; } } // fallback for equality return 0; }) } sortData(['PRICE_CODE1']); console.log(JSON.stringify(data,null,2)); sortData(['PRICE_CODE2']); console.log(JSON.stringify(data,null,2)); sortData(['PRICE_CODE3']); console.log(JSON.stringify(data,null,2));
Ответ №2:
arr.сортировка(sortByMultipleKey([‘PRICE_CODE1′,’Код модели’]))
Ваш sortByMultipleKey
берет список ключей, каждый из которых описывает один ключ. Это не может описать PRICE_CODE1
поле объекта под prices
.
По сути, вы пытаетесь придумать синтаксис для описания произвольного расположения в иерархических данных.
Вместо этого используйте сам Javascript, чтобы определить, как найти следующее поле сравнения! передайте функции, которые могут разрешать поля, и повторите их.
Ниже я определю 2 функции. Первый извлечет первый PRICE_CODE1
из элементов prices
.
function(d) { for (i = 0; i lt; d.price.length; d ) { if ("PRICE_CODE1" in d.price[i]) { return d.price[i].PRICE_CODE1 } } return undefined }
Один для кода модели проще:
function(d) { return d.modelCode }
Я также добавляю 3-ю модель с тем же PRICE_CODE1
самым, чтобы это modelCode
также было актуально.
function sortByMultiple(field_funcs) { return function(a, b) { for (i = 0; i lt; field_funcs.length; i ) { fa = field_funcs[i](a) fb = field_funcs[i](b) console.log("Comparing " fa " and " fb) if (fa lt; fb) return -1; if (fa gt; fb) return 1; if (i 1 == field_funcs.length) return 0 } } } var data = [{ "modelId": 2, "modelCode": "model2", "price": [{ "PRICE_CODE1": 100.01 }, { "PRICE_CODE2": 200.68 }, { "PRICE_CODE3": 300.0 } ] }, { "modelId": 1, "modelCode": "model1", "price": [{ "PRICE_CODE1": 225.01 }, { "PRICE_CODE2": 247.68 }, { "PRICE_CODE3": 298.0 } ] }, { "modelId": 3, "modelCode": "model3", "price": [{ "PRICE_CODE1": 225.01 }, { "PRICE_CODE2": 247.68 }, { "PRICE_CODE3": 298.0 } ] } ] data.sort(sortByMultiple([ function(d) { for (i = 0; i lt; d.price.length; d ) { if ("PRICE_CODE1" in d.price[i]) { return d.price[i].PRICE_CODE1 } } return undefined }, function(d) { return d.modelCode } ])) console.log(data)
Ответ №3:
Вы можете использовать библиотеку lodash:
_.orderBy( data, [c =gt; c.price[0].PRICE_CODE1, "modelCode"], ["asc", "asc"]);
Комментарии:
1. Эй, тебе не кажется, что это сначала разберется с wrt
PRICE_CODE1
, а затем с wrtmodelCode
. Наконец, по вашему методу массив будет отсортирован только на основеlast parameter
, предыдущая сортировка не будет иметь никакого эффекта.2. Привет, Химаншу, Ты прав. Он модифицирован.