Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 15.12.2019, 18:59
Аспирант
Отправить личное сообщение для 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.

В результате должно получится:

[
{ 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'] }
]
Ответить с цитированием
  #12 (permalink)  
Старый 15.12.2019, 19:17
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

Сообщение от Marson
В результате должно получится:
что не устраивает в коде из поста #6
Ответить с цитированием
  #13 (permalink)  
Старый 15.12.2019, 19:20
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

мутация объектов в массиве происходит, а нужно просто в result запушить. Я не прошу чтобы вы именно написали мне код, можете объяснить как это сделать? Мне важно понимать как всё происходит. Я начал код писать, а дальше застопорился
Ответить с цитированием
  #14 (permalink)  
Старый 15.12.2019, 19:39
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

Marson,
<!DOCTYPE html>
<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
</head>
<body>
<h1>исходный массив</h1>
<pre>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'] }
 ];</pre>

<h1>желаемый результат</h1><pre>
[
{ 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'] }
]</pre>
<h1>результат работы скрипта, новый массив</h1>
<script>
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.slice().map(({name, close}) => ({name, close : [...close]})).sort(comparator); //отсортировали исходный массив, согласно списка посадки
}
document.write(`<pre>${JSON.stringify(placeGuests(arr), "", 0)}</pre>`)

  </script>
<h1>найдите разницу, ниже состояние исходного массива после обработки скриптом</h1>

<script>
document.write(`<pre>${JSON.stringify(arr, "", 0)}</pre>`)
</script>
</body>
</html>
Ответить с цитированием
  #15 (permalink)  
Старый 17.12.2019, 17:10
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

Помогите понять как дописать мой код, а то запутался в цикле. В целом нужно написать по этому алгоритму: 1) сортировка по алфавиту исходного массива
2) массив результатов с первым
3) цикл, который
берет у каждого close, копирует close, отфильтровывает тех, кто уже есть в массиве-результате
пушит того, кто остался в close если есть хоть кто-то.

Берем первого гост, сажаем
За столом один человек
Берем close
Ищем имя второго
Потом шерстим изначальный список по алфавиту
И сажаем второго
Берем его 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: ['San', 'Wog'] }
 ]


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

for(var i=0; i<=arr.length; i++){
   for(let key in arr[i]){
     if(obj.close[0] === arr[i][key] || obj.close[1] === arr[i][key]){
       obj = arr[i]
       result.push(obj)
     }
}
} 
  return result;
 }

console.log(placeGuests(arr));


Я пока только к такому решению пришёл, только двоих получается усадить как надо за стол

Последний раз редактировалось Marson, 17.12.2019 в 17:14.
Ответить с цитированием
  #16 (permalink)  
Старый 17.12.2019, 17:33
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

Marson,
я же вам всё расписал ...
item.close.sort зачем это?
Ответить с цитированием
  #17 (permalink)  
Старый 17.12.2019, 18:44
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

сортируем соседей по алфавиту, а потом берём первого или второго. Ваш код сложный. Суть моего задания посадить всех людей за стол(в пустой массив), в result = []
Ответить с цитированием
  #18 (permalink)  
Старый 18.12.2019, 00:02
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

список гостей
Marson,
попытка номер ...
<script>
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: ['San', 'Wog'] }
 ];

 function placeGuests(arr) {
 /* очередь, отсортированный список гостей, те кто реально пришёл на встречу */
 let presentNameParty = arr.map(obj => obj.name).sort();
 /* будущий результат, массив, первый гость из тех кто пришёл */
 let result = presentNameParty.splice(0,1);
 /* текущий (последний) гость посаженный за стол, имя гостя */
 let current = result[0];
 /* цикл  по рассадке гостей, рассаживаем очередь гостей, пока есть кого рассаживать */
 for (;presentNameParty.length;) {
 /* номер гостя в очереди, если никого не найдём в его друзьях,
  возьмём первого из тех кто остался в очереди*/
 let index = 0;
 /* ищем друзей у текущего гостя */
 let friends = arr.find(obj => obj.name == current).close;
 /* кто из друзей стоит в очереди? */
 friends = friends.filter(name => presentNameParty.includes(name));
 /* если друзья в очереди, выбираем по алфавиту первого, сортировка */
 if(friends.length){
    current = friends.sort()[0];
    /* смотрим где стоит выбранный гость */
    index = presentNameParty.findIndex(name => name == current);
 }
 /* выводим гостя из очереди и сажаем за стол */
    current = presentNameParty.splice(index,1)[0]
    result.push(current)
 /* рассаживаем остальных гостей */
 }
 /* возвращаем список гостей за столом */
    return result
 /* не нравится список, верните массив обьектов
    return result.map(name => arr.find(obj => obj.name == name)
 */
 }

let list = placeGuests(arr)
document.write(list)
  </script>
Ответить с цитированием
  #19 (permalink)  
Старый 18.12.2019, 01:40
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

спасибо за отзывчивость
Ответить с цитированием
  #20 (permalink)  
Старый 20.12.2019, 21:08
Аспирант
Отправить личное сообщение для Marson Посмотреть профиль Найти все сообщения от Marson
 
Регистрация: 14.08.2018
Сообщений: 65

вы можете пожалуйста помочь мне дописать мой код? В конце не могу правильно рассадить гостей, т.е запушить в result. В конце нужно из arr[0] взять close, в нём найти первого сравнить с closeFilter[0] и запушить, потом из того кого запушили, с ним тоже самое сделать..

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: ['San', 'Wog'] }
 ]

 function placeGuests(arr) { 
  let result = [arr[0]];

  for(var i=0; i<arr.length; i++){
сортируем всех кто в close по алфавиту
      arr[i].close.sort((a,b) => { 
    return a > b ? 1 : -1; 
  })

отсортировываем тех, кто уже усажен из всех close, убираем
   var closeFilter = arr[i].close.filter(closeName => {
        return !result.find(friend => {
        return closeName === friend.name
  })
  })
здесь нужно запушить того, кто ещё не усажен
  var users = arr.filter(el => {
    var currentUser = arr[0]
    currentUser = el
    return currentUser.close.find(u => {
    return u === closeFilter[0]
    })
  }) 
    result.push()  
  }
        
  return result;
 }

console.log(placeGuests(arr));

Последний раз редактировалось Marson, 20.12.2019 в 22:26.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как показать элементы под картой 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