检查数组中的所有对象是否大于 x 数。

huangapple go评论60阅读模式
英文:

Check if all object in array is greater than x number

问题

我有一个表示不同城市销售数据的对象数组。每个城市都有一个包含相应计数的房间数组。我想检查是否所有城市的2号、3号和4号房间的计数都至少为3。如果满足这个条件,我想获取满足条件的所有城市的名称。

以下是数据结构的示例:

const sales = {
  "City 1": [
    {
      "rooms": 1,
      "count": 1
    },
    {
      "rooms": 2,
      "count": 2
    },
    {
      "rooms": 3,
      "count": 3
    }
  ],
  "City 2": [
    {
      "rooms": 1,
      "count": 1
    },
    {
      "rooms": 2,
      "count": 1
    },
    {
      "rooms": 3,
      "count": 1
    },
    {
      "rooms": 4,
      "count": 2
    }
  ],
  // ...其他城市数据
};

我需要协助编写一个JavaScript函数,该函数将执行此检查并返回以下内容:

  1. 一个布尔值,指示是否所有城市的2号、3号和4号房间都至少有3个计数。
  2. 如果布尔值为true,则返回满足条件的城市名称的列表。
英文:

I have an array of objects representing sales data for different cities. Each city has an array of rooms with corresponding counts. I want to check if all cities have a count of at least three for rooms 2, 3, and 4. If this condition is met, I would like to obtain the names of all the cities that satisfy it.

Here is an example of the data structure:

const sales = {
  "City 1": [
    {
      "rooms": 1,
      "count": 1
    },
    {
      "rooms": 2,
      "count": 2
    },
    {
      "rooms": 3,
      "count": 3
    }
  ],
  "City 2": [
    {
      "rooms": 1,
      "count": 1
    },
    {
      "rooms": 2,
      "count": 1
    },
    {
      "rooms": 3,
      "count": 1
    },
    {
      "rooms": 4,
      "count": 2
    }
  ],
  "City 3": [
    {
      "rooms": 2,
      "count": 6
    },
    {
      "rooms": 4,
      "count": 7
    }
  ],
  "City 4": [
    {
      "rooms": 1,
      "count": 4
    },
    {
      "rooms": 2,
      "count": 6
    },
    {
      "rooms": 3,
      "count": 3
    },
    {
      "rooms": 4,
      "count": 7
    }
  ]
};

Several solutions I tried

for (const city in sales) {
    let isPass = true;
    for (const room of sales[city]) {
      if (room.count < x) {
        isPass = false;
        break;
      }
    }
    if (isPass) {
      // do stuff here
      return true;
    }
  }

Also tried

let filteredCities = [];

  for (const city in sales) {
    const roomsData = sales[city];

    const hasRoom2 = roomsData.some((room) => room.rooms === 2);
    const hasRoom3 = roomsData.some((room) => room.rooms === 3);
    const hasRoom4 = roomsData.some((room) => room.rooms === 4);

    const isCount = roomsData.every(
      (room) => room.count >= 3
    );

    if (hasRoom2 && hasRoom3 && hasRoom4 && isCount) {
      filteredCities.push(city);
    }
  }

  return filteredCities;

I need assistance in writing a JavaScript function that will perform this check and return the following:

A boolean value indicates whether all cities have at least three counts for rooms 2, 3, and 4.
If the boolean value is true, a list of the names of the cities that satisfy the condition.

答案1

得分: 1

  1. 我想要独立检查每个城市,并选择通过测试的城市。
  2. 在房间2、3和4中,每个计数都大于等于3。

所以,当您检查每个城市时,只需要跟踪满足要求的记录。您可以通过使用一个包含相关rooms编号的Set来实现这一点。当您遍历记录时,对于每条记录,检查rooms是否同时存在于集合中并满足条件。如果为真,则从集合中删除它。当集合变为空时,您可以确保当前城市通过了测试。为每个后续城市重新填充集合并重复此过程。

以下是您提供的JavaScript代码的翻译部分:

const sales = {
  "City 1": [
    { "rooms": 1, "count": 1 },
    { "rooms": 2, "count": 2 },
    { "rooms": 3, "count": 3 }
  ],
  "City 2": [
    { "rooms": 1, "count": 1 },
    { "rooms": 2, "count": 1 },
    { "rooms": 3, "count": 1 },
    { "rooms": 4, "count": 2 }
  ],
  "City 3": [
    { "rooms": 2, "count": 6 },
    { "rooms": 4, "count": 7 }
  ],
  "City 4": [
    { "rooms": 1, "count": 4 },
    { "rooms": 2, "count": 6 },
    { "rooms": 3, "count": 3 },
    { "rooms": 4, "count": 7 }
  ]
};

function filterLocations (locations, rooms, minCount) {

    let names = Object.keys(locations);
    let found = [];

    for (let i = 0; i < names.length; i++) {

        let location = locations[names[i]];
        if (!Array.isArray(location)) {
            continue;
        }

        let set = new Set(rooms);
        for (let j = 0; j < location.length; j++) {
            let entry = location[j];
            if (set.has(entry?.rooms) && entry?.count >= minCount) {
                set.delete(entry?.rooms);
            }
            if (set.size == 0) {
                found.push(names[i]);
                break;
            }
        }
    }

    return found;
}

console.log(filterLocations(sales, [2, 3, 4], 3));

请注意,此代码的翻译是基于您提供的原始代码,未进行任何修改。

英文:

> 1. I want to check each city independently and select the one that passes the test.
> 2. Each count is >=3 in rooms 2, 3, and 4.

So when you're checking each city, you just need to keep track of records that meet the requirements. You can do this by using a Set filled with relevant rooms numbers. As you loop through the records, for each record, check if rooms is both present in the set and satisfies the condition. If true, delete it from the set. When the set becomes empty, you are sure that the current city passed the test. Refill the set for each subsequent city and repeat.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const sales = {
&quot;City 1&quot;: [
{ &quot;rooms&quot;: 1, &quot;count&quot;: 1 },
{ &quot;rooms&quot;: 2, &quot;count&quot;: 2 },
{ &quot;rooms&quot;: 3, &quot;count&quot;: 3 }
],
&quot;City 2&quot;: [
{ &quot;rooms&quot;: 1, &quot;count&quot;: 1 },
{ &quot;rooms&quot;: 2, &quot;count&quot;: 1 },
{ &quot;rooms&quot;: 3, &quot;count&quot;: 1 },
{ &quot;rooms&quot;: 4, &quot;count&quot;: 2 }
],
&quot;City 3&quot;: [
{ &quot;rooms&quot;: 2, &quot;count&quot;: 6 },
{ &quot;rooms&quot;: 4, &quot;count&quot;: 7 }
],
&quot;City 4&quot;: [
{ &quot;rooms&quot;: 1, &quot;count&quot;: 4 },
{ &quot;rooms&quot;: 2, &quot;count&quot;: 6 },
{ &quot;rooms&quot;: 3, &quot;count&quot;: 3 },
{ &quot;rooms&quot;: 4, &quot;count&quot;: 7 }
]
};
function filterLocations (locations, rooms, minCount) {
let names = Object.keys(locations);
let found = [];
for (let i = 0; i &lt; names.length; i++) {
let location = locations[names[i]];
if (!Array.isArray(location)) {
continue;
}
let set = new Set(rooms);
for (let j = 0; j &lt; location.length; j++) {
let entry = location[j];
if (set.has(entry?.rooms) &amp;&amp; entry?.count &gt;= minCount) {
set.delete(entry?.rooms);
}
if (set.size == 0) {
found.push(names[i]);
break;
}
}
}
return found;
}
console.log(filterLocations(sales, [2, 3, 4], 3));

<!-- end snippet -->

答案2

得分: 1

我认为将按id查找房间的代码与主要代码分离更清晰。我认为这样可以使代码块更易阅读。

另外,你的输出需求不是很清晰。因此,我的版本将匹配你的条件从结果的格式化中拆分出来。如果你想要输出看起来像输入对象,只是过滤出与你的条件匹配的部分,我会使用以下代码:

const findRoom = (city, roomNbr) =>
  city.find(({ rooms }) => rooms == roomNbr);

const findMatchingCities = (cities) => Object.entries(cities).filter(
  ([name, city]) => [2, 3, 4].every(roomNbr => findRoom(city, roomNbr)?.count >= 3)
);

const selectCities = (cities) =>
  Object.fromEntries(findMatchingCities(cities));

const sales = {
  "City 1": [{ rooms: 1, count: 1 }, { rooms: 2, count: 2 }, { rooms: 3, count: 3 }],
  "City 2": [{ rooms: 1, count: 1 }, { rooms: 2, count: 1 }, { rooms: 3, count: 1 }, { rooms: 4, count: 2 }],
  "City 3": [{ rooms: 2, count: 6 }, { rooms: 4, count: 7 }],
  "City 4": [{ rooms: 1, count: 4 }, { rooms: 2, count: 6 }, { rooms: 3, count: 3 }, { rooms: 4, count: 7 }]
};

console.log(selectCities(sales));

但如果你只想要匹配的城市名称,我会改用这个函数:

const selectCityNames = (cities) =>
  findMatchingCities(cities).map(([name]) => name);

你可以通过展开以下代码片段查看它:

const findRoom = (city, roomNbr) =>
  city.find(({ rooms }) => rooms == roomNbr);

const findMatchingCities = (cities) => Object.entries(cities).filter(
  ([name, city]) => [2, 3, 4].every(roomNbr => findRoom(city, roomNbr)?.count >= 3)
);

const selectCityNames = (cities) =>
  findMatchingCities(cities).map(([name]) => name);

const sales = {
  "City 1": [{ rooms: 1, count: 1 }, { rooms: 2, count: 2 }, { rooms: 3, count: 3 }],
  "City 2": [{ rooms: 1, count: 1 }, { rooms: 2, count: 1 }, { rooms: 3, count: 1 }, { rooms: 4, count: 2 }],
  "City 3": [{ rooms: 2, count: 6 }, { rooms: 4, count: 7 }],
  "City 4": [{ rooms: 1, count: 4 }, { rooms: 2, count: 6 }, { rooms: 3, count: 3 }, { rooms: 4, count: 7 }]
};

console.log(selectCityNames(sales));

无论哪种情况,主要函数 findMatchingCities 会过滤输入对象的条目,使用我们的 findRoom 来测试每个房间号码(234),并检查它们是否具有至少 3count 属性。它返回一个对象条目数组,每个条目的格式为 [城市名称, [{ rooms: 1, count: 1 }, ...]]。你可以很容易地将其合并到 selectCitiesselectCityNames 中,并删除一个函数。或者不这样做。这个分解相当清晰。

如果房间号码和/或最小计数应该是动态的,你可以轻松地向 findMatchingCities 和调用它的函数添加参数。

英文:

I find it cleaner to separate out the code that finds the rooms by id from the main code. I think it makes for more readable blocks.

Also, it wasn't clear to me what output you wanted. So my version splits out finding the object entries that match your criteria from the formatting of their results. If you wanted the output to look like the input object, just filtered to keep those that match your criteria, I would use this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const findRoom = (city, roomNbr) =&gt;
city.find(({rooms}) =&gt;  rooms == roomNbr)
const findMatchingCities = (cities) =&gt; Object.entries(cities).filter (
([name, city]) =&gt; [2, 3, 4].every(roomNbr =&gt; findRoom(city, roomNbr)?.count &gt;= 3)
)
const selectCities = (cities) =&gt; 
Object.fromEntries(findMatchingCities(cities))
const sales = {&quot;City 1&quot;: [{rooms: 1, count: 1}, {rooms: 2, count: 2}, {rooms: 3, count: 3}], &quot;City 2&quot;: [{rooms: 1, count: 1}, {rooms: 2, count: 1}, {rooms: 3, count: 1}, {rooms: 4, count: 2}], &quot;City 3&quot;: [{rooms: 2, count: 6}, {rooms: 4, count: 7}], &quot;City 4&quot;: [{rooms: 1, count: 4}, {rooms: 2, count: 6}, {rooms: 3, count: 3}, {rooms: 4, count: 7}]}
console .log (selectCities(sales))

<!-- language: lang-css -->

.as-console-wrapper {max-height: 100% !important; top: 0}

<!-- end snippet -->

But if you just wanted the matching ciy names, I would use this function instead:

const selectCityNames = (cities) =&gt; 
  findMatchingCities(cities).map(([name]) =&gt; name)

You can see it by expanding the following snippet:

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

const findRoom = (city, roomNbr) =&gt;
city.find(({rooms}) =&gt;  rooms == roomNbr)
const findMatchingCities = (cities) =&gt; Object.entries(cities).filter (
([name, city]) =&gt; [2, 3, 4].every(roomNbr =&gt; findRoom(city, roomNbr)?.count &gt;= 3)
)
const selectCityNames = (cities) =&gt; 
findMatchingCities(cities).map(([name]) =&gt; name)
const sales = {&quot;City 1&quot;: [{rooms: 1, count: 1}, {rooms: 2, count: 2}, {rooms: 3, count: 3}], &quot;City 2&quot;: [{rooms: 1, count: 1}, {rooms: 2, count: 1}, {rooms: 3, count: 1}, {rooms: 4, count: 2}], &quot;City 3&quot;: [{rooms: 2, count: 6}, {rooms: 4, count: 7}], &quot;City 4&quot;: [{rooms: 1, count: 4}, {rooms: 2, count: 6}, {rooms: 3, count: 3}, {rooms: 4, count: 7}]}
console .log (selectCityNames(sales))

<!-- language: lang-css -->

.as-console-wrapper {max-height: 100% !important; top: 0}

<!-- end snippet -->

In either case, the main function, findMatchingCities filters the entries of our input object, using our findRoom for each of the room numbers we want to test (2, 3, 4), and checking if they have a count property of at least 2. It returns an array of object entries, each in the form [&#39;CityName&#39;, [{rooms: 1, count: 1}, ...]] You could easily fold this into selectCities or selectCityNames and remove one function. Or not. This breakdown is fairly clean.

If the room numbers and/or the minimum count should be dynamic, it's trivial to add parameters to findMatchingCities and the function that calls it.

答案3

得分: 0

我找到了一个解决方案,我能够通过迭代每个城市并检查每个城市中房间2、3和4的计数是否>= 3来解决它。

以下是代码部分的中文翻译:

const sales = {
  "City 1": [{
    rooms: 1,
    count: 1
  }, {
    rooms: 2,
    count: 2
  }, {
    rooms: 3,
    count: 3
  }],
  "City 2": [{
    rooms: 1,
    count: 1
  }, {
    rooms: 2,
    count: 1
  }, {
    rooms: 3,
    count: 1
  }, {
    rooms: 4,
    count: 2
  }],
  "City 3": [{
    rooms: 2,
    count: 6
  }, {
    rooms: 4,
    count: 7
  }],
  "City 4": [{
    rooms: 1,
    count: 4
  }, {
    rooms: 2,
    count: 6
  }, {
    rooms: 3,
    count: 3
  }, {
    rooms: 4,
    count: 7
  }]
};

function checkCity(cities) {
  const availableCities = [];

  for (const city in cities) {
    const rooms = cities[city];

    const room2 = rooms.find(room => room.rooms === 2);
    const room3 = rooms.find(room => room.rooms === 3);
    const room4 = rooms.find(room => room.rooms === 4);

    if (room2 && room3 && room4 && room2.count >= 3 && room3.count >= 3 && room4.count >= 3) {
      availableCities.push(city);
    }
  }

  return availableCities;
}

console.log(checkCity(sales));

请注意,以上是代码部分的中文翻译,不包括问题或其他内容。

英文:

I found a solution,

I was able to solve it by iterating over each city and checking if the count for rooms 2, 3, and 4 is >= 3 in each city

Here:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const sales = {
&quot;City 1&quot;: [{
rooms: 1,
count: 1
}, {
rooms: 2,
count: 2
}, {
rooms: 3,
count: 3
}],
&quot;City 2&quot;: [{
rooms: 1,
count: 1
}, {
rooms: 2,
count: 1
}, {
rooms: 3,
count: 1
}, {
rooms: 4,
count: 2
}],
&quot;City 3&quot;: [{
rooms: 2,
count: 6
}, {
rooms: 4,
count: 7
}],
&quot;City 4&quot;: [{
rooms: 1,
count: 4
}, {
rooms: 2,
count: 6
}, {
rooms: 3,
count: 3
}, {
rooms: 4,
count: 7
}]
};
function checkCity(cities) {
const availableCities = [];
for (const city in cities) {
const rooms = cities[city];
const room2 = rooms.find(room =&gt; room.rooms === 2);
const room3 = rooms.find(room =&gt; room.rooms === 3);
const room4 = rooms.find(room =&gt; room.rooms === 4);
if (room2 &amp;&amp; room3 &amp;&amp; room4 &amp;&amp; room2.count &gt;= 3 &amp;&amp; room3.count &gt;= 3 &amp;&amp; room4.count &gt;= 3) {
availableCities.push(city);
}
}
return availableCities;
}
console.log(checkCity(sales)); 

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月16日 03:05:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76484784.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定