在数组中匹配2个元素

时间:2018-02-28 12:04:36

标签: javascript arrays ecmascript-5

假设我有一个人类

class Person {
    constructor(name, sign, likes) {
        this.name = name;
        this.sign = sign;
        this.likes = likes
    }
}

var a = new Person("Jim", "virgo", "piscis");
var b = new Person("Sara", "sagitarus", ["piscis", "sagitarus"]);
var c = new Person("Sam", "aries", "Leo");

本课程描述了他们的十二生肖,以及他们最喜欢的十二生肖。

然后,我有一群人:

var people = [a, b, c, ....]

我想要实现的是,从数组的开始,根据他们的符号和他们感兴趣的内容找到第一个可能的匹配。

例如:

  • 如果数组中的第一项是符号白羊座的人对符号处女座感兴趣的人,请在数组中搜索第一个符号感兴趣的处女座的人在白羊座

  • 如果数组中的第一项是符号白羊座对处女座感兴趣的人,但数组中没有人是对白羊座感兴趣的处女座,然后继续尝试匹配阵列中的下一个人。

  • 如果数组中的第一项是符号白羊座的人对有白羊座的人感兴趣的人,请在数组中搜索第一个拥有对白羊座感兴趣的符号处女座的人, 但不包括他自己

我期望得到的是:

  • 两人匹配
  • 相同的人群,但是从列表中删除了那些人

这样的事情:

var match = matchPair(my_people_array);
// match is an array of 2 Persons
// match is falsy in case of no matches
// my_people_array is 2 items shorter (or a new array, not necessary to modify the original array)

我昨天试图解决它很长一段时间,但即使接近工作,我也无法找到任何解决方案。

我怎样才能在JS中实现这个结果?

更新

由于我不想给人的印象是我自己没有先尝试过任何事情,所以这是我能想到的最好的,即使我知道它不起作用:

function match(people) {
    for (var i = 0; i < people.length; i++) {
        var person = people[i];
        var match = people.find((candidate)) {
            return candidate !== person && candidate.likes.includes(person.sign) && person.likes.includes(candidate.sign)
        }

        if (!match) return false

        return [person, match]
    }
}

虽然这让我得到了一些比赛,但我也让不止一组的人匹配

更新2:

我会提出一些问题,看看这个想法是否得到了更明确的解释

// CASE 1

var persons = [
    new Person("Jim", "virgo", ["aries"]),
    new Person("John", "aries", ["virgo"])
    new Person("Justin", "aries", ["piscis"])
];

matchCouple(persons)
// returns an array with Jim and John
// "persons" contains Justin only

// CASE 2

var persons = [
    new Person("Jim", "virgo", ["virgo"]),
    new Person("John", "virgo", ["virgo"])
];

matchCouple(persons)
// returns an array with Jim and John
// Beware not to pair Jim with himself
// "persons" is empty

// CASE 3

var persons = [
    new Person("Jim", "virgo", ["aries"]),
    new Person("John", "piscis", ["virgo"])
];

matchCouple(persons)
// returns falsy value
// persons does not change

// CASE 4

var persons = [
    new Person("Justin", "aries", ["piscis"]),
    new Person("Jim", "virgo", ["aries"]),
    new Person("John", "aries", ["virgo"])
];

matchCouple(persons)
// returns an array with Jim and John, skipping Justin because he had no matches
// "persons" contains Justin only

3 个答案:

答案 0 :(得分:1)

在这里,我们会减少您的人数,并根据原始数组中的第一个人(ss)与人likes

找到匹配项

&#13;
&#13;
let people = [
	{ss: 'aries', likes: 'virgo'},
  {ss: 'cancer', likes: 'scorpio'},
  {ss: 'virgo', likes: 'aries'},
  {ss: 'scorpio', likes: 'virgo'},
  {ss: 'cancer', likes: 'virgo'},
  {ss: 'sagitarius', likes: 'sagitarius'}
]

const CREATE_MATCH_ARRAY = () => {
	let matches = people.reduce((pre, person, i, orig) => {
  	pre.push([person, orig.find(p => person.likes === p.ss)])
    return pre
  }, [])
  
  return matches
}

console.log(CREATE_MATCH_ARRAY())
&#13;
&#13;
&#13;

我可以看到的一个问题是你的people数组具有唯一标识符,以便如果某个人对象看起来像{ss: 'aries', likes: 'aries'}并不最终与自身匹配。

让我们看看我们能做些什么。

&#13;
&#13;
let people = [
	{ss: 'aries', likes: 'aries', ID: 1},
  {ss: 'cancer', likes: 'scorpio', ID: 2},
  {ss: 'virgo', likes: 'aries', ID: 3},
  {ss: 'scorpio', likes: 'virgo', ID: 4},
  {ss: 'cancer', likes: 'virgo', ID: 5},
	{ss: 'aries', likes: 'cancer', ID: 7},
  {ss: 'sagitarius', likes: 'sagitarius', ID: 6}
]

const CREATE_MATCH_ARRAY = () => {
	let matches = people.reduce((pre, person, i, orig) => {
  	pre.push([
      person, 
      orig
      .filter(p => p.ID !== person.ID)
      .find(p => person.likes === p.ss)])
    return pre
  }, [])
  
  return matches
}

console.log(CREATE_MATCH_ARRAY())
&#13;
&#13;
&#13;

处理多个likes

的代码

&#13;
&#13;
let people = [
	{ss: 'aries', likes: 'aries', ID: 1},
  {ss: 'cancer', likes: 'scorpio', ID: 2},
  {ss: 'virgo', likes: 'aries', ID: 3},
  {ss: 'scorpio', likes: ['virgo', 'aries', 'cancer'], ID: 4},
  {ss: 'cancer', likes: 'virgo', ID: 5},
	{ss: 'aries', likes: 'cancer', ID: 7},
  {ss: 'sagitarius', likes: 'sagitarius', ID: 6}
]

const CREATE_MATCH_ARRAY = () => {
	let matches = people.reduce((pre, person, i, orig) => {
  	let filteredOriginal = orig.filter(p => p.ID !== person.ID)
  	pre.push([
      person, 
      filteredOriginal
      .filter(p => p.ID !== person.ID)
      .filter(p => {
      	if (Array.isArray(person.likes)) {
        	return filteredOriginal.filter(p => person.likes.indexOf(p.ss) !== -1)
        }
        else {
        	return person.likes === p.ss      
        }
       })])
    return pre
  }, [])
  
  return matches
}

console.log(CREATE_MATCH_ARRAY())
&#13;
&#13;
&#13;

答案 1 :(得分:1)

为什么不通过创建双向工作方法来实现这一点?

&#13;
&#13;
Post::whereIn('user_id', auth()->user()->friends()->pluck('id'))->get()
&#13;
const convertToArray = val => typeof val === 'string' ? [ val ] : val;

class Person {
  constructor(name, sign, compatibleSigns) {
    this.name = name;
    this.sign = sign;
    this.compatibleSigns = convertToArray(compatibleSigns);
  }
  likes(otherPerson) {
    if (otherPerson == null) {
      return false;
    }
    return this.compatibleSigns.indexOf(otherPerson.sign) > -1;
  }
  isLikedBy(otherPerson) {
    if (otherPerson == null || otherPerson.compatibleSigns == null) {
      return false;
    }
    return otherPerson.compatibleSigns.indexOf(this.sign) > -1;
  }
  isCompatible(otherPerson) {
    return this.likes(otherPerson) && this.isLikedBy(otherPerson);
  }
  likesSelf() {
    return this.likes(this);
  }
}

var a = new Person("Jim", "virgo", ["sagitarus", "piscis"]);
var b = new Person("Sara", "sagitarus", ["piscis", "sagitarus", "virgo"]);
var c = new Person("Sam", "aries", "Leo");

console.log(a.likes(b));        // True
console.log(a.isLikedBy(b));    // True
console.log(b.isCompatible(a)); // True
console.log(b.likesSelf());     // True
&#13;
&#13;
&#13;

答案 2 :(得分:0)

你可以使用find和filter来帮助,并检查两种方式的匹配。

以下是一个例子:

for dns in $(aws ec2 describe-instances --region ap-northeast-1 --query 'Reservations[*].Instances[*].PublicDnsName' --output text) ; do echo $dns ; done