Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 25.11.2019, 23:51
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

как сортировать вложенные элементы по алфавиту?
Дан список гостей.
 У каждого есть имя и список имен близких друзей, с кем человек себя комфортно чувствует.
 Изначально список отсортирован по алфавиту (по полю "name").
 Посадите гостей за круглый стол так, чтобы человека окружали только его близкие друзья.
 Отдавая предпочтение списку по алфавиту.
 
 Например:
 
 Входящий массив (аргумент "arr")
 [
    { name: 'Ali', close: ['Vasil', 'Wog'] },
    { name: 'San', close: ['Vasil', 'Zena'] },
    { name: 'Vasil', close: ['San', 'Ali'] },
    { name: 'Wog', close: ['Zena', 'Ali'] },
    { name: 'Zena', close: ['Sun', 'Wog'] }
 ]

 Поскольку входящий массив отсортирован по алфавиту, на первом месте объект с "name" == "Ali".
 Там его и оствляем, и ищем соседа. В массиве "close" у этого объекта находятся "Vasil" и "Wog".
 Кого из этих двоих посадить следующим, выбираем по алфавиту. В данном случае - это "Vasil".
 Располагаем объект c name == "Vasil" после "Ali".
 Чтобы узнать следующего, смотрим "close" у объекта "Vasil". Там находяться "San" и "Ali".
 По алфавиту, из этих двоих следующим должен быть "Ali", но он уже занял свое место, поэтому
 следующим будет "San". И так далее.
 В итоге гости должны сидеть в следующем порядке Ali, Vasil, Sun, Zena, Wog.
 
 В результате выполнения вашего кода должен получиться отсортированный массив,
 который необходимо передать в вызов функции "finish".
 В данном примере, этот массив будет выглядеть следующим образом
  
[
    { name: 'Ali', close: ['Vasil', 'Wog'] },
    { name: 'Vasil', close: ['San', 'Ali'] },
    { name: 'San', close: ['Vasil', 'Zena'] },
    { name: 'Zena', close: ['Sun', 'Wog'] },
    { name: 'Wog', close: ['Zena', 'Ali'] }    
 ]


нужно применить map() и sort()?
Ответить с цитированием
  #2 (permalink)  
Старый 26.11.2019, 00:52
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

Marson,
шифровка из центра ...
const arr = [
        { name: 'Ali', close: ['Vasil', 'Wog'] },
        { name: 'San', close: ['Vasil', 'Zena'] },
        { name: 'Vasil', close: ['San', 'Ali'] },
        { name: 'Wog', close: ['Zena', 'Ali'] },
        { name: 'Zena', close: ['Sun', 'Wog'] }
 ];

const setName = new Set(arr.map(({name}) => name));
let curent = 'Ali'
let list = [curent];
for (let i = 0; i < arr.length-1; i++) {
        let {close} = arr.find(({name}) => name == curent);
        curent = close.find( name => setName.has(name) && !list.includes(name))
        if(!curent) {
          [curent, ...a] = setName;
        }
        list.push(curent);
        setName.delete(curent)
}
console.log(list)
list = list.map(n => arr.find(({name}) => name == n))
console.table(list)
Ответить с цитированием
  #3 (permalink)  
Старый 26.11.2019, 08:38
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

А если будет массив с другими именами, можно же сделать общее решение для любых данных?
Ответить с цитированием
  #4 (permalink)  
Старый 26.11.2019, 09:09
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

Сообщение от Marson
А если
вы проверили этот код с другими данными?
разве что вместо let curent = 'Ali'
сделать
let curent = arr[0].name;
Ответить с цитированием
  #5 (permalink)  
Старый 26.11.2019, 13:46
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

проверял работает, спасибо. Хочу написать общую функцию:

function placeGuests (arr) {
  let result = [];
  
  ........
  
  return result;
}
Ответить с цитированием
  #6 (permalink)  
Старый 26.11.2019, 14:37
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

Marson,
const arr = [
        { name: 'Ali', close: ['Vasil', 'Wog'] },
        { name: 'San', close: ['Vasil', 'Zena'] },
        { name: 'Vasil', close: ['San', 'Ali'] },
        { name: 'Wog', close: ['Zena', 'Ali'] },
        { name: 'Zena', close: ['Sun', 'Wog'] }
 ];



function placeGuests(arr) {
    const collator = new Intl.Collator(["en", "ru"], {numeric: true});//создали сортировщик
    let comparator = (a, b) => collator.compare(a, b);//создали функцию сортировки
    let [curent, ...list] = arr.map(({name}) => name).sort(comparator);//получили список имён по алфавиту ["Ali", "San", "Vasil", "Wog", "Zena"]
    const setName = new Set(list); // ["San", "Vasil", "Wog", "Zena"] список имён для списка посадки
    list = [curent];//['Ali'] список посадки
    for(;setName.size;) { // пока список имён не пуст
    let {close} = arr.find(({name}) => name == curent);// нашли друзей Ali ['Vasil', 'Wog']
    curent = close.find( name => setName.has(name)); // нашли 'Vasil'
    if(!curent) [curent, ..._] = setName; //если в списке друзей нет подходящего, берём первого из списка имён
    list.push(curent);//добавили друга в список посадки
    setName.delete(curent)//удалили друга из списка имён
    };
   //создали список посадки list ["Ali", "Vasil", "San", "Zena", "Wog"]
    comparator = (a, b) => collator.compare(list.indexOf(a.name), list.indexOf(b.name));//создали функцию сортировки согласно местам посадки
    return arr.sort(comparator); //отсортировали исходный массив, согласно списка посадки
}
console.table(placeGuests(arr))

Последний раз редактировалось рони, 26.11.2019 в 15:33.
Ответить с цитированием
  #7 (permalink)  
Старый 26.11.2019, 15:03
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

Спасибо, код крутой, но мне как начинающему не всё понятно..
Думал код должен быть по проще, буду разбираться..
Ответить с цитированием
  #8 (permalink)  
Старый 26.11.2019, 15:32
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

Marson,
добавил пояснение.
Ответить с цитированием
  #9 (permalink)  
Старый 15.12.2019, 15:52
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

подскажите как найти в close следующего ближайшего друга и вставить его следующим в name или сразу всем объектом с нужным name and close, а то который уже усажен убрать и взять второго. Нужно вывести новый массив, т.е. сделать push() в result. Нельзя чтобы входной массив мутировал и выводился, нужно вывести новый массив. имена в close я расставил по алфавиту..

let arr = [
    { name: 'Ali', close: ['Vasil', 'Wog'] },
    { name: 'San', close: ['Vasil', 'Zena'] },
    { name: 'Vasil', close: ['San', 'Ali'] },
    { name: 'Wog', close: ['Zena', 'Ali'] },
    { name: 'Zena', close: ['Sun', 'Wog'] }
 ]


 function placeGuests (arr) { 
  let result = [];
 arr.forEach((item, index, array) => {
  item.close.sort((a,b) => { 
    return a > b ?  1 : -1;
  })
     item.close.filter((arr, i) => {
       
        }      
})
  })
  return result;
}

console.log(placeGuests(arr))
Ответить с цитированием
  #10 (permalink)  
Старый 15.12.2019, 16:06
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

Marson,
не понимаю, может покажите результат, который хотите получить?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как показать элементы под картой zava75 Элементы интерфейса 3 13.07.2018 18:48
Как вывести элементы по очереди каждый через несколько секунд? AsceticTr jQuery 3 27.05.2018 16:59
Как показывать/скрывать элементы с одинаковым div? Sice Javascript под браузер 6 13.11.2017 01:44
Как перерисовать все элементы SVG на Canvas (d3.js+leaflet.js+html2canvas) Trippal Общие вопросы Javascript 0 10.02.2016 18:25
Как выровнять элементы li в jquery ui tabs? 1Dmitry Элементы интерфейса 2 23.03.2013 14:58