Сортировка массива объектов в зависимости от значений другого массива Javascript

У меня есть два массива: Первый массив:

SelectedRows= 
[
   {
      "NR":"4",
      "KUNNR":"9?AMT132",
      "NAME":" AUTO TOURING HANDELS GES.M.B.H.",
      "LATLON":[
         15.4114217,
         47.0664085
      ],
      "LIN":"LIN097"
   },
   {
      "NR":"3",
      "KUNNR":"9Z?CH005",
      "NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH",
      "LATLON":[
         13.4216536,
         47.3747925
      ],
      "LIN":"LIN099"
   },
   {
      "NR":"2",
      "KUNNR":"9SMTA001",
      "NAME":" SMT AUTOTEILE",
      "LATLON":[
         13.2277803,
         47.9525892
      ],
      "LIN":"LIN0102"
   },
   {
      "NR":"1",
      "KUNNR":"9REIT051",
      "NAME":" W.REITINGER GMBH",
      "LATLON":[
         14.4017044,
         48.2213305
      ],
      "LIN":"LIN0103"
   }
]

Второй массив

LOCATIONS =
[
   [
      15.4114217,
      47.0664085
   ],
   [
      14.4017044,
      48.2213305
   ],
   [
      13.2277803,
      47.9525892
   ],
   [
      13.4216536,
      47.3747925
   ]
]

Мне нужно отсортировать первый массив (SelectedRows) по совпадающим значениям из SelectedRows.LATLON во втором массиве (LOCATIONS).

Я пытался сделать:

var Output= LOCATIONS.filter(function(obj) { 
            return SelectedRows.LATLON.indexOf(obj) == -1; 
        });

но это не сработало. Так что, если кто-нибудь может дать мне совет, я буду так благодарен. Извините за мой плохой английский, чтобы понять, что я публикую ожидаемый результат:

Ожидаемый результат:

Output=[
{
    "NR":"4",
    "KUNNR":"9?AMT132",
    "NAME":" AUTO TOURING HANDELS GES.M.B.H.",
    "LATLON":[
        15.4114217,
        47.0664085
    ],
    "LIN":"LIN097"
},
{
    "NR":"1",
    "KUNNR":"9REIT051",
    "NAME":" W.REITINGER GMBH",
    "LATLON":[
        14.4017044,
        48.2213305
    ],
    "LIN":"LIN0103"
},
{
    "NR":"2",
    "KUNNR":"9SMTA001",
    "NAME":" SMT AUTOTEILE",
    "LATLON":[
        13.2277803,
        47.9525892
    ],
    "LIN":"LIN0102"
},
{
    "NR":"3",
    "KUNNR":"9Z?CH005",
    "NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH",
    "LATLON":[
        13.4216536,
        47.3747925
    ],
    "LIN":"LIN099"
}]

Спасибо за вашу помощь

I tried a lot покажи как ты вообще старался
Bravo 20.03.2022 23:48

Извините, что отредактировал пост.

Safwan Al Najjar 20.03.2022 23:52

ваша проблема в том, что вы не понимаете, что возвращает фильтр, вам не нужно фильтровать, вам нужно отобразить - также locations не то же самое, что LOCATIONS, а SelectedRows - это массив, поэтому у него не будет свойства LATLON

Bravo 20.03.2022 23:53

Большое спасибо за объяснение. Это очень помогает. Поскольку я нахожусь в своей квартире, страдая от этой ковы, и так устал думать, что упустил правильный образ мыслей. С наилучшими пожеланиями.

Safwan Al Najjar 21.03.2022 00:03

В несвязанной заметке вы должны проверить свою кодировку. «Zöchner Erdbau», вероятно, должно быть «Zöchner Erdbau» с немецким умлаутом ö.

Mushroomator 21.03.2022 00:22

@Mushroomator Спасибо за совет, но да, кодировка уже в порядке в FE. но сейчас я работаю на своем персональном компьютере, на котором нет службы поддержки Deutsch.

Safwan Al Najjar 21.03.2022 00:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
41
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Самый быстрый способ (по крайней мере, асимптотически) сделать это за O(n) время, если у вас есть n элементов как в selectedRows, так и в locations, заключается в следующем.

  1. Перебрать местоположения, которые являются порядком верный, и сопоставить значения местоположения с индексом, в котором они (должны быть). Вы не можете использовать для этого массив как таковой, поскольку массивы нельзя сравнивать с помощью Object.is(), который Map использует внутри. Таким образом, вы можете, например, использовать здесь объединенную строку. Могут быть варианты лучше/чище, но это просто и делает свою работу. Это займет O(n).

Тогда карта будет выглядеть так:

Map(4) {
  '15.4114217,47.0664085' => 0,
  '14.4017044,48.2213305' => 1,
  '13.2277803,47.9525892' => 2,
  '13.4216536,47.3747925' => 3
}
  1. Прокрутите selectedRows и для каждого объекта определите его ключ, который снова является объединенным местоположением, и с помощью этого ключа получите индекс, в котором объект должен находиться в O(1). Если текущий индекс и целевой индекс совпадают, все в порядке. Если нет, нам нужно поменять объект на целевой индекс, что, очевидно, делается в O(1). В сумме это тоже займет O(n).

Готово. В совокупности шаги займут O(n) времени, и поэтому это будет асимптотически оптимальный алгоритм.

const selectedRows = 
[
   {
      "NR":"4",
      "KUNNR":"9?AMT132",
      "NAME":" AUTO TOURING HANDELS GES.M.B.H.",
      "LATLON":[
         15.4114217,
         47.0664085
      ],
      "LIN":"LIN097"
   },
   {
      "NR":"3",
      "KUNNR":"9Z?CH005",
      "NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH",
      "LATLON":[
         13.4216536,
         47.3747925
      ],
      "LIN":"LIN099"
   },
   {
      "NR":"2",
      "KUNNR":"9SMTA001",
      "NAME":" SMT AUTOTEILE",
      "LATLON":[
         13.2277803,
         47.9525892
      ],
      "LIN":"LIN0102"
   },
   {
      "NR":"1",
      "KUNNR":"9REIT051",
      "NAME":" W.REITINGER GMBH",
      "LATLON":[
         14.4017044,
         48.2213305
      ],
      "LIN":"LIN0103"
   }
]

const locations =
[
   [
      15.4114217,
      47.0664085
   ],
   [
      14.4017044,
      48.2213305
   ],
   [
      13.2277803,
      47.9525892
   ],
   [
      13.4216536,
      47.3747925
   ]
]

console.info("Previous", selectedRows);

const indexMap = new Map();

// Map values to indices
locations.forEach((loc, idx) => indexMap.set(`${loc[0]},${loc[1]}`, idx));

// put each object to the correct position
selectedRows.forEach((row , i) => {
    // concatenate lookup key
    const key = `${row.LATLON[0]},${row.LATLON[1]}`;
    // check if value is actually in map => should always be the case (assumption: locations and showLocation contain the same locations)
    if (indexMap.has(key)){
        const targetIndex = indexMap.get(key);
        // check if the object is at the right position
        if (!targetIndex === i){
            // position is wrong => swap positions
            const temp = selectedRows[i];
            selectedRows[i] = selectedRows[targetIndex];
            selectedRows[targetIndex] = temp;
        }
    }
})

console.info("After", selectedRows);

Note: you would need to make sure that the two variables locations and selectedRows actually contain the same locations and are of equal length.

Ответ принят как подходящий

то, что вы должны делать, это картаLOCATIONS

в карте вы найти соответствующий пункт в SelectedRows...

имейте в виду, что [1,2] !== [1,2] поэтому вы не можете сравнивать массивы в своей находке, так как вы никогда ничего не найдете - либо сравните каждый элемент массивов, либо, в этом случае, вы можете проверить, если array1.join() === array2.join()

const SelectedRows = [ { "NR":"4", "KUNNR":"9?AMT132", "NAME":" AUTO TOURING HANDELS GES.M.B.H.", "LATLON":[ 15.4114217, 47.0664085 ], "LIN":"LIN097" }, { "NR":"3", "KUNNR":"9Z?CH005", "NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH", "LATLON":[ 13.4216536, 47.3747925 ], "LIN":"LIN099" }, { "NR":"2", "KUNNR":"9SMTA001", "NAME":" SMT AUTOTEILE", "LATLON":[ 13.2277803, 47.9525892 ], "LIN":"LIN0102" }, { "NR":"1", "KUNNR":"9REIT051", "NAME":" W.REITINGER GMBH", "LATLON":[ 14.4017044, 48.2213305 ], "LIN":"LIN0103" } ], LOCATIONS = [ [ 15.4114217, 47.0664085 ], [ 14.4017044, 48.2213305 ], [ 13.2277803, 47.9525892 ], [ 13.4216536, 47.3747925 ] ] 

const output =  LOCATIONS.map(
  a=>SelectedRows.find(({LATLON}) => LATLON.join() === a.join())
);

console.info(output);
.as-console-wrapper {max-height: 100%!important; top:0; }
.as-console-row::after { display:none !important; }

Хотя для действительно читаемого кода

const SelectedRows = [ { "NR":"4", "KUNNR":"9?AMT132", "NAME":" AUTO TOURING HANDELS GES.M.B.H.", "LATLON":[ 15.4114217, 47.0664085 ], "LIN":"LIN097" }, { "NR":"3", "KUNNR":"9Z?CH005", "NAME":" Z?CHNER ERDBAU U TRANSPORT GMBH", "LATLON":[ 13.4216536, 47.3747925 ], "LIN":"LIN099" }, { "NR":"2", "KUNNR":"9SMTA001", "NAME":" SMT AUTOTEILE", "LATLON":[ 13.2277803, 47.9525892 ], "LIN":"LIN0102" }, { "NR":"1", "KUNNR":"9REIT051", "NAME":" W.REITINGER GMBH", "LATLON":[ 14.4017044, 48.2213305 ], "LIN":"LIN0103" } ], LOCATIONS = [ [ 15.4114217, 47.0664085 ], [ 14.4017044, 48.2213305 ], [ 13.2277803, 47.9525892 ], [ 13.4216536, 47.3747925 ] ] 

const output = LOCATIONS.map(([tgtLat, tgtLon]) =>
  SelectedRows.find(
    ({ LATLON: [lat, lon] }) => tgtLat === lat && tgtLon === lon
  )
);

console.info(output);
.as-console-wrapper {max-height: 100%!important; top:0; }
.as-console-row::after { display:none !important; }

Следующий код немного грязный, но он работает:

LOCATIONS_ORDER = LOCATIONS.map(e => `${e[0]};${e[1]}`);
SelectedRows.forEach(e => e.index = LOCATIONS_ORDER.indexOf(`${e.LATLON[0]};${e.LATLON[1]}`));

SelectedRows.sort((a,b) => a.index-b.index);

console.info(SelectedRows);
.sort ... зачем вам sort, если LOCATIONS находится в нужном порядке?
Bravo 21.03.2022 00:08

Я сортирую "SelectedRows", а не "LOCATIONS"

Veso Alex 21.03.2022 00:13

действительно - но зачем вы что-то сортируете?

Bravo 21.03.2022 00:32

Другие вопросы по теме